为什么redux状态不更新?

时间:2020-11-06 13:12:54

标签: reactjs redux react-redux

一切似乎对我来说很好,控制台日志可以在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;
    }

}

还有我的root Reducer

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

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

我将感谢任何适用的解决方案/说明。。谢谢

1 个答案:

答案 0 :(得分:1)

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

如果是这样,则需要映射如下属性:

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

否则,您需要重新制作userInputReducerinitialState才能删除双重嵌套。

一切似乎对我来说很好,控制台日志可以在Action和Reducer中运行,但是Chrome Redux工具不会触发任何操作,也不会显示状态更新。

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

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

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

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