简体   繁体   中英

Why does function used in mergeProps not update when redux store/state updates?

I have a state nextBoxID in the redux store and action + reducer that updates a boxID when a button is pressed.

Issue I am having is that the store updates as expected on button press, but the function that uses the nextBoxID from the state does not update.

const getNewBoxDispatch = (dispatch) => {

    /*
       Inner function used as onPress in a Button. 
       State is updated to the next ID, but the nextBoxID parameter doesn't update.
    */
    const newBoxDispatch = (nextBoxID) => () => {

        dispatch(addNewBox(nextBoxID))
        dispatch(updateToNextID());

        console.log('In newBoxDispatch: \n')
        console.log('nextBoxID - ' + nextBoxID + ' (Initial boxID is 0)')
    };

    return newBoxDispatch;
}


const mapStateToProps = (state) => ({
    newBoxID: state.nextBoxID,
})

const mapDispatchToProps = (dispatch) => ({
    addNewBoxDispatch: getNewBoxDispatch(dispatch)
})

const mergeProps = (stateProps, dispatchProps, ownProps) => {

    const newBoxID = stateProps.newBoxID;

    console.log('In mergeProps: \n')
    console.log('newBoxID - ' + newBoxID)

    const addNewExperiment = dispatchProps.addNewBoxDispatch(newBoxID);

    return({
        ...stateProps,
        ...dispatchProps,
        ...ownProps,
        addNewExperiment
    })
}

export default connect(
    mapStateToProps,
    mapDispatchToProps,
    mergeProps
)(Home)

When the button is pressed the store is updated with a newBoxID , but the nextBoxID parameter of newBoxDispatch doesn't update.

So for example we can get an output of:

In mergeProps:
newBoxID - 4

In newBoxDispatch:
nextBoxID - 0 (Initial boxID is 0)

What is going on ?

There are very few times you actually need to use mergeProps . In addition, your current code seems very odd in general.

It's much simpler if you write the logic as a thunk, and either pass in the ID as a parameter when your component calls it, or read the value from the store in the thunk itself. Examples:

function addNewBoxFromParam(nextBoxID) {
    return (dispatch, getState) => {
        dispatch(addNewBox(nextBoxID))
        dispatch(updateToNextID());
    }
}

function addNewBoxFromState() {
    return (dispatch, getState) => {
        const {nextBoxID} = getState();
        dispatch(addNewBox(nextBoxID))
        dispatch(updateToNextID());
    }
}

const mapState = (state) => ({
    newBoxID: state.nextBoxID,
})


const actionCreators = {
    addNewBoxFromParam,
    addNewBoxFromState,
};

class MyComponent extends React.Component {
    onAddFromParamClicked = () => {
        this.props.addNewBoxFromParam(this.props.newBoxID);
    }

    render() {
        return (
            <div>
                <button onClick={this.onAddFromParamClicked}>Add From Param</button>
                <button onClick={this.props.addNewBoxFromState}>Add From State</button>
            </div>
        );
    }
}

export default connect(mapState, actionCreators)(MyComponent);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM