简体   繁体   中英

Change in state do not propagate in props

I have the "classic" issue with the React redux about not propagating the change in state into the props when I try to access it in the component.

Here I have read that

99.9% of the time, this is because you are accidentally mutating data, usually in your reducer

Can you tell me what am I doing wrong? Is this the good way how to do the deep copy of the property of the specified object in array?

note: in the reducer in the return statement the state is clearly changed correctly (debugged it)

reducer:

case 'TOGGLE_SELECTED_TAG':
        const toggledTagId = action.payload;

        const index = findItemById(state.tags, toggledTagId);
        const newTags = state.tags.slice(0);
        if(index >= 0)
        {
            newTags[index] = Object.assign(
                state.tags[index], 
                {selected: !state.tags[index].selected});

            state.tags = newTags;
        }

        return Object.assign({}, state);

component:

import React from 'react';
import { Button, FormControl, Table, Modal } from 'react-bootstrap';
import { connect } from 'react-redux';
import axios from 'axios';

import {selectTagAction} from '../../actions/actions'

@connect((store) => {
return {
    tags: store.TagsReducer.tags,
}
})

export default class AssignTag extends React.Component {
constructor(props) {
    super(props);

    this.handleTagClick = this.handleTagClick.bind(this);
}

handleTagClick(element) {
    debugger;
    this.props.dispatch(selectTagAction(element));
}

 render() {
    const tags = this.props.tags;
    console.log(tags);
    const mappedTags = tags.map(tag => {
        return (
            <div className="col-sm-12" key={tag.id} onClick={() => this.handleTagClick(tag.id)}
                style={{background: this.getBackgroundColor(tag.selected)}}>
                <span>{tag.name}</span>
            </div>
        )
    })

// code continues
}

}

You are indeed mutating the state. Try this:

case 'TOGGLE_SELECTED_TAG':
        const toggledTagId = action.payload;
        const index = findItemById(state.tags, toggledTagId);
        let newTags = state;
        if( index >= 0 )
        {
            newTags[index] = Object.assign(
                {},
                state.tags[index],
                { selected: !state.tags[index].selected }
              );
            //state.tags = newTags;   This line essentially mutates the state
            return Object.assign( {}, state, { tags: newTags });
        }

        return state;

避免状态突变的另一种解决方法是在减速器中使用ES6速记:

....   return { ...state, tags : newTags };

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