【问题标题】:Why doesn't the redux state update?为什么 redux 状态不更新?
【发布时间】:2020-11-06 13:12:54
【问题描述】:

对我来说一切都很好,控制台日志在 Action 和 Reducer 中工作,但 Chrome Redux 工具显示没有触发任何操作,也没有状态更新。

这是我的组件类

import React, { Component } from 'react'
import { connect } from 'react-redux'
import { SimpleGrid,Box,Select,Input,InputGroup,InputRightAddon,Text,Heading ,Button,NumberInput,NumberInputField,} from "@chakra-ui/core";
import { Footer } from '../../layout/Main/components';
import {submitUserInput} from '../../utils/actions/userInput'
import PropTypes from 'prop-types';

 class UserInput extends Component {
    
    constructor(props) {
        super(props);
        this.handleSubmit = this.handleSubmit.bind(this)
        this.state = {
            yieldStress:0,
            thickness:0,
            diameter:0,
            pMAX:0
        }
        this.handleChange = this.handleChange.bind(this)
    }
    handleSubmit=(event)=>{
        event.preventDefault();
        console.log(this.state);
        this.props.submitUserInput(this.state);
    }

    handleChange=(event)=>{
        this.setState({[event.target.name]:event.target.value});
    }

    render(){
        const materialsList = this.props.materials.map((material)=>(
        <option value={material.yieldStress} key={material.id}>{material.name}</option>
        ));

    return (
        <Box>
        <Heading as="h4" size="md">Cylinder Details</Heading>
    <Text>{this.props.thickness}</Text>
        <form onSubmit={this.handleSubmit} >
            <Select placeholder="Select Material of Cylinder" isRequired name="yieldStress" onChange={this.handleChange}>
                    {materialsList}
            </Select>
            <SimpleGrid columns={2} spacing={8} padding="16px 0px">
                <Box>
                    <InputGroup>
                        <InputRightAddon children="(mm)"/>
                        <Input type="number" placeholder="Thickness of Cylinder"  roundedRight="0" isRequired name="thickness" onChange={this.handleChange}/>
                    </InputGroup>
                </Box>
                <Box>
                    <InputGroup>
                        <InputRightAddon children="(mm)"/> 
                        <Input type="number" placeholder="Diameter of Cylinder" roundedRight="0" isRequired name="diameter"onChange={this.handleChange}/>
                    </InputGroup>
                </Box>
            </SimpleGrid>
            <SimpleGrid columns={2} spacing={8} padding="0px 0px">
                <Box>
                    <InputGroup>
                        <InputRightAddon children={<Text paddingTop="12px">(N/mm)<sup>2</sup></Text>} padding="0 4px"/>
                        
                        <NumberInput precision={2} step={0.2}  >
                            <NumberInputField  placeholder="Maximum pressure "  roundedRight="0" isRequired name="pMAX" onChange={this.handleChange}/>
                        </NumberInput>
                    </InputGroup>
                </Box>
                <Box>
                    <InputGroup>
                        <InputRightAddon children="(mm)"/> 
                        <Input type="number" placeholder="Factor of Saftey" roundedRight="0" isRequired name="FOS"onChange={this.handleChange}/>
                    </InputGroup>
                </Box>
            </SimpleGrid>
            <Box padding="8px 0" >
            <Button variantColor="teal" float="right" border="0"  type="submit">Submit</Button>
            </Box>
        </form>
        <Footer />
    </Box>
  
    )
}
 }

UserInput.protoTypes = {
    submitUserInput: PropTypes.func.isRequired,
    thickness: PropTypes.string.isRequired,
 }
const mapStateToProps = (state) => ({
    thickness: state.userInput.thickness
})

const mapDispatchToProps = dispatch => {
    return {
    submitUserInput: (userInput)=> dispatch(submitUserInput(userInput))
}}

export default connect(mapStateToProps, mapDispatchToProps)(UserInput)

这是我的动作文件

import { SUBMIT_REQUEST_SENT,SUBMIT_SUCCESS,SUBMIT_FAILURE} from '../types'
export const submitUserInput = ({yieldStress, FOS, diameter,pMAX,thickness }) => async (dispatch) => {
    dispatch(submitRequestSent());
    try {
        console.log("Printing object in action")
        console.log({yieldStress, FOS, diameter,pMAX,thickness }) //This is Printed 
        dispatch({
            type: SUBMIT_SUCCESS,
            payload:{yieldStress, FOS, diameter,pMAX,thickness } 
        }
        );
    }
    catch (error) {
        dispatch({
            type: SUBMIT_FAILURE,
            payload: error.message
        })
        throw error;
    }

}

export const submitRequestSent = () =>
({
    type: SUBMIT_REQUEST_SENT,
})

这是 UserInput Reducer

import {
SUBMIT_REQUEST_SENT,SUBMIT_SUCCESS,SUBMIT_FAILURE
} from '../../actions/types'

const initialState = {
        userInput:{
            yieldStress:0,
            FOS:0,
            diameter:0,
            pMAX:0,
            thickness:0 
        }
    }

export default function (state = initialState, action) {
    switch (action.type) {
        case SUBMIT_REQUEST_SENT:
            return {
                ...state,
            }
        case SUBMIT_SUCCESS:
            console.log("Submit has been sucessfull And below is the Payload"); //This is Printed
            console.log(action.payload)//This is Printed
            return {
                ...state,
                userInput:action.payload
            }
            
        case SUBMIT_FAILURE:
            return {
                ...state,
                error: action.payload
            }
        default:
            return state;
    }

}

还有我的根减速器

import {combineReducers} from 'redux';
import  authReducer from '../authReducer'
import userInputReducer from '../userInputReducer';

export default  combineReducers(
    {
        auth:authReducer,
        userInput:userInputReducer
    }
)

我会感谢任何适用的解决方案/解释..谢谢

【问题讨论】:

  • 因为您没有处理组件中的 props 更改。要接收组件中的更改,您必须在 Component Class 组件中使用 componentWillReceiveProps(props) 来处理 props 更改。然后更新状态。
  • @fahadali 他确实将this.props.thickness 直接映射到渲染中,您的评论不是问题
  • @isaac 你能把你的代码上传到 sanbox 吗?我最好的猜测是因为 thickness 嵌套在 state obj 和 userInput obj 中,您可能需要在某处对渲染进行一些处理
  • @HagaiHarari 然后他应该检查道具是否在 render() 中更新。如果它没有更新,请使用 componentWillReceiveProps(props) 检查。
  • @HagaiHarari 我认为它至少应该在 Redux 开发工具中显示更新,而不是在组件中显示映射问题

标签: reactjs redux react-redux


【解决方案1】:

在您的州内,您有一个名为userInput 的属性,它是由userInputReducer 控制的州部分。该部分有自己的属性,也称为userInput,用于存储实际数据。是你想要的吗?

如果是这样,您需要像这样映射属性:

const mapStateToProps = (state) => ({
    thickness: state.userInput.userInput.thickness
})

如果没有,您需要重新处理您的 userInputReducerinitialState 以移除双重嵌套。

对我来说一切都很好,控制台日志在 Action 和 Reducer 中工作,但 Chrome Redux 工具显示没有触发任何操作,也没有状态更新。

在我看来,这听起来像是调度异步 thunk 动作的问题。如果没有适当的中间件,Redux 无法处理这些类型的操作。创建商店时,它应该是这样的:

import reducer from "./reducer";
import {createStore, applyMiddleware} from "redux";
import thunk from "redux-thunk";

const store = createStore(reducer, applyMiddleware(thunk));

我复制并发布了您的减速器代码,并使用上述设置的商店。我使用了一个虚拟组件(单击时增加 thickness 的按钮),我无法重现您的问题。这让我相信问题出在商店本身的配置上。

【讨论】:

    猜你喜欢
    • 2017-01-25
    • 2021-02-17
    • 1970-01-01
    • 1970-01-01
    • 2020-03-30
    • 2020-12-07
    • 1970-01-01
    • 2020-08-01
    相关资源
    最近更新 更多