【问题标题】:Reactjs setState() with a dynamic key name?具有动态键名的 Reactjs setState()?
【发布时间】:2015-05-30 14:04:37
【问题描述】:

编辑:这是重复的,请参阅here

我找不到任何在设置状态时使用动态键名的示例。这就是我想做的:

inputChangeHandler : function (event) {
    this.setState( { event.target.id  : event.target.value } );
},

其中 event.target.id 用作要更新的状态键。这在 React 中是不可能的吗?

【问题讨论】:

  • 这是关于动态对象键的任何问题的副本。反应不具体
  • var newstate = {};新状态[event.target.id] = event.target.id; this.setState(newstate);
  • 谢谢,我一般没有很好地使用对象。
  • @trad 我遇到了这个问题,但是,您在初始状态中设置了什么?没关系吧?

标签: javascript reactjs computed-properties


【解决方案1】:

感谢@Cory 的提示,我使用了这个:

inputChangeHandler : function (event) {
    var stateObject = function() {
      returnObj = {};
      returnObj[this.target.id] = this.target.value;
         return returnObj;
    }.bind(event)();

    this.setState( stateObject );    
},

如果使用 ES6 或 Babel transpiler 转换您的 JSX 代码,您也可以使用 computed property names 完成此操作:

inputChangeHandler : function (event) {
    this.setState({ [event.target.id]: event.target.value });
    // alternatively using template strings for strings
    // this.setState({ [`key${event.target.id}`]: event.target.value });
}

【讨论】:

  • 如果你使用 bablejs 来构建你的代码,还有一个新的语法。你可以使用computed property names
  • 第二种方法会导致 WIndows(IE、Chrome)浏览器出现语法错误。有人注意到了吗?
  • 如何表述?
  • 感谢trad,这是我为避免<Radio /> 实现的代码重复而寻找的。​​span>
  • 如果您使用这样的计算属性名称设置状态:this.setState({ [event.target.id]: event.target.value });,那么您将如何使用 this.state...... 访问该状态?
【解决方案2】:

当需要处理多个受控输入元素时,可以给每个元素添加一个name属性,让handler函数根据event.target.name的值来选择做什么。

例如:

inputChangeHandler(event) {
  this.setState({ [event.target.name]: event.target.value });
}

【讨论】:

  • [event.target.name] 周围的括号表示什么?为什么需要它们?
  • 与通常的方法相比,将每个元素分别命名为 this.setState({ userName: e.target.value });这会将表单的多个元素作为数组处理,无需设置每个单独的元素
  • 但我仍然如何以相同的方式访问该状态?喜欢this.state([event.target.name]) ?
  • 我认为 MDN web docsthis post 解释了为什么我们需要括号。
【解决方案3】:

我是如何做到的...

inputChangeHandler: function(event) {
  var key = event.target.id
  var val = event.target.value
  var obj  = {}
  obj[key] = val
  this.setState(obj)
},

【讨论】:

  • 我做了类似的方法,但问题是它仍然没有渲染组件,我跑了柱子来发布(包括这个:D),在某个地方发现了这个:this.forceUpdate();这不应该是最新 React 的案例。让我们稍后看看是什么问题!
【解决方案4】:

我只是想补充一点,您还可以使用解构来重构代码并使其看起来更整洁。

inputChangeHandler: function ({ target: { id, value }) {
    this.setState({ [id]: value });
},

【讨论】:

    【解决方案5】:

    我也遇到过类似的问题。

    我想设置第二级密钥存储在变量中的状态。

    例如this.setState({permissions[perm.code]: e.target.checked})

    但这不是有效的语法。

    我使用以下代码来实现这一点:

    this.setState({
      permissions: {
        ...this.state.permissions,
        [perm.code]: e.target.checked
      }
    });
    

    【讨论】:

      【解决方案6】:

      .map 的循环中工作如下:

      {
          dataForm.map(({ id, placeholder, type }) => {
              return <Input
                  value={this.state.type}
                  onChangeText={(text) => this.setState({ [type]: text })}
                  placeholder={placeholder}
                  key={id} />
          })
      }
      

      注意type 参数中的[]。 希望这会有所帮助:)

      【讨论】:

        【解决方案7】:
        this.setState({ [`${event.target.id}`]: event.target.value}, () => {
              console.log("State updated: ", JSON.stringify(this.state[event.target.id]));
            });
        

        请注意引号字符。

        【讨论】:

        • 正是我需要的。
        【解决方案8】:

        我一直在寻找一个漂亮而简单的解决方案,我发现了这个:

        this.setState({ [`image${i}`]: image })
        

        希望对你有帮助

        【讨论】:

          【解决方案9】:

          使用 ES6+ 你可以做到 [${variable}]

          【讨论】:

            【解决方案10】:

            当给定元素是一个对象时:

            handleNewObj = e => {
                    const data = e[Object.keys(e)[0]];
                    this.setState({
                        anykeyofyourstate: {
                            ...this.state.anykeyofyourstate,
                            [Object.keys(e)[0]]: data
                        }
                    });
                };
            

            希望对某人有所帮助

            【讨论】:

              【解决方案11】:

              您的状态与字典更新一些键而不会丢失其他值

              state = 
              {   
                  name:"mjpatel"  
                  parsedFilter:
                  {
                    page:2,
                    perPage:4,
                    totalPages: 50,
                  }
              }
              

              解决方法如下

               let { parsedFilter } = this.state
               this.setState({
                    parsedFilter: {
                      ...this.state.parsedFilter,
                      page: 5
                    }
                });
              

              此处更新值为 5 的关键“页面”的值

              【讨论】:

                【解决方案12】:

                可以使用扩展语法,如下所示:

                inputChangeHandler : function (event) {
                    this.setState( { 
                        ...this.state,
                        [event.target.id]: event.target.value
                    } );
                },
                

                【讨论】:

                • React 会为你合并对象,这是不好的做法。
                • 基本上,如果您有一些内部对象并且您想更改该内部对象的一个​​属性,您可以这样做:this.setState({selectedItems:{...selectedItems,[item.id] :true}})
                • @Rohmer:为什么这被认为是不好的做法?如果一个对象有多个键,使用扩展运算符似乎可以保留除被修改的键之外的所有其他键。还是我们应该使用 prevState ?请解释一下。
                • 如果你有像@EranOr 提到的嵌套状态,那么进行传播是有意义的,但你必须使用prevState 否则你将无法保证你使用的是最新的-日期状态。但是,如果您只是像@sta 的答案那样设置单个顶级状态值,那么您不需要传播状态,因为 React 会为您合并它。 reactjs.org/docs/…
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2017-09-05
                • 2018-03-28
                • 1970-01-01
                • 2016-05-12
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多