Search code examples
javascriptreactjsreduxreact-redux

Why my I am not able to print sum of numbers from react-redux state?


Can somebody please help me in knowing why I am not able to reflect "sum" which is the sum to two numbers passed from the input box values "numOne" and "numTwo" on the UI. Please refer AddNum.jsx.

Below is the action.js

'use strict';

export const ADD_NUMBERS = 'ADD_NUMBERS';
export const RESET = 'RESET';

export const addNum = () => {
    return {
        "type" : ADD_NUMBERS,
    }
}

export const reset = () => {
    return {
        "type" : RESET
    }
}

Below is AddNumReducer.js

'use strict';

import {ADD_NUMBERS, RESET} from './action';

const addNumReducer = (state = { "sum" : 0}, action) => {
    console.log(`AddNumReducer: sum ${state.sum}`);
    console.log(`AddNumReducer: action.type ${action.type}`);
    switch(action.type){
        case ADD_NUMBERS:
            return {
                "sum" : state.sum
            }
        case RESET:
            return {
                "sum" : 0
            }
        default:
            return state;    
    }
}

export default addNumReducer;

Below is AddNumContainer.js

import AddNum from './AddNum';
import * as ActionCreator from './action';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';

const mapStateToProps = (state) => {
    return {
        "sum" : state.addNums.sum        
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        "actions" : bindActionCreators(ActionCreator, dispatch)
    }
}

const AddNumContainer = connect(mapStateToProps, mapDispatchToProps)(AddNum); 

export default AddNumContainer;

Below is reducer.js

'use strict';

import { combineReducers } from 'redux';
import addNumReducer from './AddNumReducer';

export default combineReducers({
  "addNums" : addNumReducer
});

Below is AddNum.jsx

'use strict';
import React, {Component, Fragment, useState} from 'react';


const AddNum = (props) => {
    const [stateObj, setStateObj] = useState({
        "numOne" : "",
        "numTwo" : ""
    });

    const [counterStyle, setCounterStyle] = useState({
        "fontSize" : "350px",
        "fontWeight" : "bold",
        "color" : "#483d8b"
    });

    const obj = {
        "sum" : props.sum,         
        "actions" : props.actions
    }
    
    const submitForm = () => {
        let total = parseInt(stateObj.numOne) + parseInt(stateObj.numTwo);                               
        obj.actions.addNum({
            "sum" : total
        });
    }

    return (
        <Fragment>
            <form className="form-inline">
                <div className="form-group">
                    <label  for="numOneId" 
                            className="sr-only">Num One</label>
                    <input  type="text" 
                            className="form-control" 
                            id="numOneId" 
                            placeholder="Num One" 
                            value={stateObj.numOne}
                            onChange={event => setStateObj({
                                ...stateObj,  
                                "numOne" : event.target.value
                            })} />
                </div>
                &nbsp;
                <div className="form-group">
                    <label  for="numTwoId" 
                            className="sr-only">Num Two</label>
                    <input  type="text" 
                            className="form-control" 
                            id="numTwoId" 
                            placeholder="Num Two"
                            value={stateObj.numTwo} 
                            onChange={(event) =>{
                                setStateObj({
                                    ...stateObj,
                                    "numTwo" : event.target.value
                                });
                            }}/>
                </div>
                &nbsp;
                <button type="button" 
                        className="btn btn-primary"
                        onClick={submitForm}>Add</button>
                &nbsp;
                <button type="button" 
                        className="btn btn-default"
                        onClick={obj.actions.reset}>Reset</button>        
            </form>
            <div>
                <span style={counterStyle}>{obj.sum}</span>
            </div>
        </Fragment>
    )
     
}

export default AddNum;

Below is AddNumUI.jsx

'use strict';
import React, {Component, Fragment} from 'react';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import AddNumContainer from './AddNumContainer';
import rootReducer from './reducer';

const store = createStore(rootReducer);

const AddNumUI = () => {
    return (
        <Provider store={store}>
            <AddNumContainer />
        </Provider>
    );
} 

export default AddNumUI;

Solution

  • There is an issue with your actions and reducer. You are not using the action.payload value in your addNum action inside the reducer. Also, you are not correctly updating the state of the store. You need to spread the existing state and then update the sum value to the new value.

    AddNum.jsx

    const submitForm = () => {
        let total = parseInt(stateObj.numOne) + parseInt(stateObj.numTwo); 
        obj.actions.addNum({
            sum: total       // action.payload.sum
        });
    }
    

    action.js

    export const ADD_NUMBERS = 'ADD_NUMBERS';
    export const RESET = 'RESET';
    
    export const addNum = (value) => {
        return {
            type: ADD_NUMBERS,
            payload: value
        }
    }
    
    export const reset = () => {
        return {
            type: RESET
        }
    }
    

    AddNumReducer.js

    import { ADD_NUMBERS, RESET } from './action';
    
    const initialState = { sum: 0 }
    
    const addNumReducer = (state = initialState, action) => {
        switch (action.type) {
            case ADD_NUMBERS:
                return {
                    ...state,
                    sum: action.payload.sum
                };
            case RESET:
                return {
                    ...state,
                    sum: 0
                };
            default:
                return state;
        }
    }
    
    export default addNumReducer;