【问题标题】:Setting state within a React method在 React 方法中设置状态
【发布时间】:2018-12-10 02:22:18
【问题描述】:

我有一个将值 (e) 传递给过滤器的 React 组件,e 将始终是以下值之一:{true, false, SHOW_ALL}。

filterItem(e) {  
    this.state.filter[0].Status = e.target.value;
    this.setState({
         filter: this.state.filter
    });
 }

React 抱怨我正在直接修改状态。收到此警告:不要直接改变状态。使用 setState()

我不知道如何将过滤器状态设置为 e.target.value,并包含在 setState() 的赋值中;要设置状态,我必须将 e.target.value 分配给 Status 属性,如下所示:

 this.state.filter[0].Status = e.target.value;

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    而不是像这样直接分配它:

    this.state.filter[0].Status = e.target.value;
    

    你可以这样做。

    this.setState({filter: [{status: e.target.value}] })
    

    【讨论】:

    • 谢谢。这个就像第一响应者。感谢您抽出宝贵时间提出建议
    • @Rachel,如果我的回答解决了你的问题,请采纳。
    【解决方案2】:

    首先,您需要创建现有数组的副本

    const filter = [...this.state.filter]

    然后你可以改变这个副本

    filter[0].Status = e.target.value;

    然后你可以使用 setState

    this.setState({filter: filter})

    【讨论】:

    • 谢谢!我也试过这个并且有效。感谢您抽出宝贵时间提出建议!
    • @JonasW。是的,这是真的,我忘记了,谢谢。
    【解决方案3】:
    filterItem(e) {
        this.setState({
            filter: e.target.value
        });
    }
    

    this.state.filter[0].Status = e.target.value; 直接改变状态。您直接为状态分配值,而不是使用提供的 setState() 函数。如您收到的警告所述,这违反了 React 的 3 个关键原则之一。

    还有一点需要注意:Status 是一个保留字,因此您不应该将它用作属性名称。

    另外,this.state.filter[0].Status 意味着 this.state.filter 是一个数组,并且您正在更改其第一个元素的属性 Status。除非this.state.filter 需要保存多个元素/项目,每个元素/项目都有自己的Status 属性,否则您可以将其保留为this.state.filter

    如果这是故意的,那么您可以将函数更改为:

    filterItem(e) {
        this.setState({
            filter: [{Status: e.target.value}]
        });
    }
    

    【讨论】:

    • 你提到它很好,但我不认为这里使用Status 不好。部分是因为它是大写的(保留字都是小写的),部分是因为它是对象的键而不是变量
    • 谢谢!我现在明白了。你对我如何实施事情提出了一些非常重要的观点。实际上,我正在将一堆来自不同来源的代码重构为我要编写的代码。效果很好!
    • 不过,你们都提出了一些好的观点。它基本上只是 Todo's 的状态属性。 filter[x] 的 Array 部分是我在这里使用了一些键/值对... [0] 用于待办事项状态,[1] 用于搜索词,但我想我会将它们拆分为单独的组件。这里不需要使用数组。谢谢你。
    • status 不是保留字,但应该是驼峰式以遵守约定
    • @chris 哪个保留字?我错过了什么吗?
    【解决方案4】:

    其实有点复杂:

    this.setState(previous => ({
         filter: [{
            ...previous.filter[0],
            Status: e.target.value
         }].concat(previous.filter.slice(1))
    }));
    

    PS:这是我更喜欢简单而不是严格的状态转换的情况之一,所以忽略警告;)

    【讨论】:

    • 这也很有趣,并且以不同的方式看待这个问题。这里的一切都没有 Redux。谢谢!
    猜你喜欢
    • 2018-06-30
    • 2021-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-30
    相关资源
    最近更新 更多