Ad

Redux State Updates Two Seperate Objects

I have influencer data object. This object is beeing pulled from database with action FETCH_INFLUENCER and put inside two different objects: influencer and formInfluencer in redux store. And then I have action SET_INFLUENCER that is supposed to create new instance of the state and update influencer object in redux. For some reason though it updates both influencer and formInfluencer. I really struggle with finding answer here since I think I did everything to prevent pointing of two different variables to the same object and still it happens.

reducer:

    case 'FETCH_INFLUENCER_FULFILLED':
        return { ...state, fetching: false, fetched: true, influencer: action.payload.data, formInfluencer: Object.assign([], action.payload.data) }
    case 'SET_INFLUENCER':
        return { ...state, influencer: action.payload }

actions:

export function fetchInfluencer(id) {
return {
    type: "FETCH_INFLUENCER",
    payload: axios.get('/api/influencer/' + id, {headers: {Authorization: 'Bearer ' + localStorage.getItem('token')}})
}
}
export function setInfluencer(influencer) {
return {
    type: "SET_INFLUENCER",
    payload: influencer
}
}

dispatch:

 handleUserChange(e) {
    let influencer = [...this.props.influencer]
    influencer[0].user[e.target.name] = e.target.value;
    this.props.dispatch(setInfluencer(influencer))
}

mapping state to props:

const mapStateToProps = (state) => {
return {
    influencer: state.influencers.influencer,
    formInfluencer: state.influencers.formInfluencer
}
}
export default connect(mapStateToProps)(InfluencerDetails)

If You have any idea why this could be happening I would be happy to hear the answer.

Ad

Answer

You shouldn't mutate state (if you don't mutate it, then it is no problem that you have multiple variables pointing to the same object).

Instead of:

handleUserChange(e) {
    let influencer = [...this.props.influencer]
    influencer[0].user[e.target.name] = e.target.value;
    this.props.dispatch(setInfluencer(influencer))
}

You should do a bit more work:

handleUserChange(e) {
    const newUser = {
        ...this.props.influencer[0].user,
        [e.target.name]: e.target.value
    };
    const newInfluencer = {
        ...this.props.influencer[0],
        user: newUser
    };
    const newInfluencers = [...this.props.influencer];
    newInfluencers[0] = newInfluencer;

    this.props.dispatch(setInfluencer(newInfluencers));
}
Ad
source: stackoverflow.com
Ad