Reactjs 状态变化不会在道具中传播

Reactjs 状态变化不会在道具中传播,reactjs,redux,Reactjs,Redux,我在React redux中遇到了一个“经典”问题,即当我尝试在组件中访问道具时,没有将状态中的更改传播到道具中 我已经读过了 99.9%的情况下,这是因为您意外地改变了数据,通常是在您的减速器中 你能告诉我我做错了什么吗?这是在数组中对指定对象的属性进行深度复制的好方法吗 注意:在return语句中的reducer中,状态明显正确更改(已调试) 减速器: case 'TOGGLE_SELECTED_TAG': const toggledTagId = action.payloa

我在React redux中遇到了一个“经典”问题,即当我尝试在组件中访问
道具时,没有将
状态中的更改传播到
道具中

我已经读过了

99.9%的情况下,这是因为您意外地改变了数据,通常是在您的减速器中

你能告诉我我做错了什么吗?这是在数组中对指定对象的属性进行深度复制的好方法吗

注意:在return语句中的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);
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
}
组件:

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);
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
}
从“React”导入React;
从“react bootstrap”导入{Button,FormControl,Table,Modal};
从'react redux'导入{connect};
从“axios”导入axios;
从“../../actions/actions”导入{selectTagAction}
@连接((存储)=>{
返回{
标记:store.TagsReducer.tags,
}
})
导出默认类AssignTag扩展React.Component{
建造师(道具){
超级(道具);
this.handleTagClick=this.handleTagClick.bind(this);
}
把手舔(元件){
调试器;
此.props.dispatch(selectTagAction(元素));
}
render(){
const tags=this.props.tags;
控制台日志(标签);
const mappedTags=tags.map(tag=>{
返回(
this.handleTagClick(tag.id)}
style={{background:this.getBackgroundColor(tag.selected)}>
{tag.name}
)
})
//代码继续
}

}你确实在改变这种状态。试试这个:

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 };

这个声明在做什么<代码>常量newTags=state.tags.slice(0)?能否更新代码以显示完整的减速器?包括函数头?如果我更改
let newTags,您的代码就可以工作带有
const newTags=state.tags.slice(0)。你能再描述一下为什么这条线会改变状态吗?不是那条线。行
state.tags=newTags
是通过更改其中一个键的值来改变状态的行。我的意思是您的代码不工作,抛出错误
Uncaught TypeError:无法设置未定义的属性“0”
,因此我修改了您的行
let newTags带有
const newTags=state.tags.slice(0)。现在它起作用了。当我改变状态的时候,你说的也对,对不起。忘了。你不需要对状态进行切片。您可以按原样复制它
让newTags=state。只要你不改变状态就好。