Isaac Pitwa
Isaac Pitwa

Reputation: 410

Why doesn't the redux state update?

Everything Seems Fine to me, the Console logs work in the Action and in the Reducer but the Chrome Redux tools show no action being trigged and no state updates.

Here is my Component Class

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)

Here is My Action File

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,
})

And Here is the 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;
    }

}

And my root Reducer

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

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

I will Appreciate any applicable solution/Explanation..thanks

Upvotes: 0

Views: 117

Answers (1)

Linda Paiste
Linda Paiste

Reputation: 42288

Within your state you have a property called userInput, which is the state section controlled by userInputReducer. That section has its own property which is also called userInput that stores the actual data. It that what you intended?

If so, you need to map properties like this:

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

If not, you need to rework your userInputReducer and initialState to remove the double nesting.

Everything Seems Fine to me, the Console logs work in the Action and in the Reducer but the Chrome Redux tools show no action being trigged and no state updates.

This sounds to me like an issue with dispatching an asynchronous thunk action. Redux cannot handle these types of actions without the appropriate middleware. When you create the store, it should be something like this:

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

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

I copy and posted your reducer code with a store set up as above. I used a dummy component ( a button that increments thickness when clicked ) and I was not able to reproduce your issue. That leads me to believe that the issue is in the configuration of the store itself.

Upvotes: 1

Related Questions