1
votes

Redux: Undefined Prop

Undefined Prop I want to pass down a prop from my container component, down to my presentational component via props, but I haven't been able to do so without the prop being undefined. Why isn't the number prop being passed down to the presentational component?

Creating the store with the initial stae and rootreducer:

import {createStore, applyMiddleware} from 'redux';
...
import rootReducer from './reducers/rootReducer';

const initialState = {
    multiply: 2,
    number: 1
}

export const store = createStore(
    ...initialState, 
    rootReducer, 
    applyMiddleware(logger(), thunk),
    window.devToolsExtension && window.devToolsExtension()
);

Reducer for multiply actions and divide actions:

const multiplyReducer = (state = {}, action) => {
    switch (action.type) {
        case 'MULTIPLY':
            return state = {
                ...state,
                number: state.number * action.payload
            }
        case 'DIVIDE':
            return state = {
                ...state,
                number: state.number / action.payload
            }
        default:
            return state;
    }
}

export default multiplyReducer;

Root reducer:

import {combineReducers} from 'redux';
import multiplyReducer from './multiplyReducer';

const rootReducer = combineReducers({
  multiply: multiplyReducer
});

export default rootReducer;

Wrapping the app in a Provider:

import Multiplier from './ContainerComponents/Multiplier';
import { BrowserRouter, Route } from 'react-router-dom';

const App = ({ store }) => (
    <BrowserRouter>
        <Route path="/" exact component={Multiplier}/>
    </BrowserRouter>
);

export default App;

Actions:

export const multiplyAction = {
    type: 'MULTIPLY',
    payload: 2
}

export const divideAction = {
    type: 'DIVIDE',
    payload: 2
}

Container Component:

    import MultiplierDisplay from '../StyleComponents/MultiplierDisplay';
    import {connect} from 'react-redux';
    import {multiplyAction, divideAction} from '../Redux/actions/multiplyActions';

    class Multiplier extends React.Component {

        render() {

            return (<MultiplierDisplay {...this.props} />)
        }
    };

    const mapStateToProps = (state) => {
        return {multiply: state.multiply, number: state.number}
    };

    const mapDispatchToProps = (dispatch) => {
        return {
            handleClick: (event) => {
                dispatch(multiplyAction)
            },
            handleClick2: (event) => {
                dispatch(divideAction)
            }
        }
    }

    export default connect(mapStateToProps, mapDispatchToProps)(Multiplier);

Presentational Component:

const MultiplierDisplay = (props) => {

        return (
            <div
                className="top"
                style={{
                alignContent: 'center',
                justifyContent: 'center'
            }}>
                <div className="App">
                    <header className="App-header">
                        <img src={logo} className="App-logo" alt="logo"/>
                        <h1 className="App-title">Welcome to React</h1>
                    </header>
                </div>
                <h1 style={{
                    marginLeft: 20
                }}>
                    Multiply the count:
                </h1>
                <p style={{
                    fontSize: '3em'
                }}>
                    Count: {props.number}
                </p>
                <button
                    style={{
                    marginLeft: 100,
                    width: '20%',
                    height: '20%'
                }}
                    onClick={props.handleClick}
                    title="Multiply">
                    Multiply
                </button>
                <button
                    style={{
                    marginLeft: 50,
                    width: '20%',
                    height: '20%'
                }}
                    onClick={props.handleClick2}
                    title="Divide">
                    Divide
                </button>
            </div>
        )
    }

    export default MultiplierDisplay;
3

3 Answers

0
votes

You can use this below to your code

 const mapStateToProps = (state) => {
        return {multiply: state.multiply.multiply, number: state.multiply.number}
    };
0
votes

Your prop number isn't passed on to the presentation component being you haven't passed it down from the container,

class Multiplier extends React.Component {

    render() {

        return (<MultiplierDisplay/>)   // this is where you are not passing it down
    }
};

If you need to pass all the props down to the MultiplierDisplay component you can write

class Multiplier extends React.Component {

    render() {

        return (<MultiplierDisplay {...this.props}/>)
    }
};

or if you want to pass selected props down, you can write them like

class Multiplier extends React.Component {

    render() {
        const { multiply, number, handleClick, handleClick2 } = this.props;
        return (<MultiplierDisplay multiply={multiply} number={number} handleClick={handleClick} handleClick2={handleClick2}/>)
    }
};

Also you need to get the state from state.multiple you are having number and multiply in multiplierReducer which you are using as multiply

const mapStateToProps = (state) => {
    return {multiply: state.multiply.multiply, number: state.multiply.number}
};

const mapDispatchToProps = (dispatch) => {
    return {
        handleClick: (event) => {
            dispatch(multiplyAction)
        },
        handleClick2: (event) => {
            dispatch(divideAction)
        }
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(Multiplier);
0
votes

There is a problem in how you are mapping you state to props of your Multiplier component as written in combineReducer you have added multiply as the state name for your multiplyReducer, hence in your mapStateToProps function you need to can access your multiplyReducer state by the following code:

const mapStateToProps = (state) => {
    return {multiply: state.multiply.multiply, number: state.multiply.number}
};

Thanks I hope this helps.