首页 > 解决方案 > React - 动态设置状态,无需硬编码关键字段

问题描述

在 ES6 中,ComputedPropertyName 允许我们做一些事情,比如使用变量作为键,这反过来意味着我们可以动态设置状态。但是,如果您查看动态设置状态的示例,它们往往都有一个共同点——状态键的名称是硬编码的。举个例子:

class Input extends React.Component {
    state = { state1: "" };

    handleChange = event => {
        const {
            target: { name, value }
        } = event;

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

    render() {
        return (
            <div>
                <label>
                    <input
                        type="text"
                        name="state1"
                        value="new value"
                        onChange={this.handleChange}
                    />
                </label>
            </div>
        );
    }
}

这是因为我们有一个名为“state1”的状态键,如行中所示state = { state1: "" };,并且我们将输入字段中的名称硬编码为该状态键,如行中所示name="state1"

我不喜欢这个解决方案,因为这意味着我现在必须跟踪state.state1" in more than one location. If I were to refactorstate.state1 to instead bestate.state2 , I would have to go findname="state1"1 并将其更新为 read name="state2"。与其担心这一点,我想知道是否有一种方法可以动态设置状态而不用硬编码这个状态键。也就是说,我正在寻求改变

<input
      type="text"
      name="state1"
      value="new value"
      onChange={this.handleChange}
      />

变成这样的东西:

<input
      type="text"
      name={this.state.state1.keyname}
      value="new value"
      onChange={this.handleChange}
      />

显然,上面的内容不起作用,因为keyname未定义,但这里的意图是 name 可以采用“state1”的值,而无需我对其进行硬编码。如何做到这一点?

标签: javascriptreactjs

解决方案


您可以拥有一个包含带有键的对象的数组typename您可以使用它来设置初始状态并动态呈现输入。这样,您只需在数组中更改一次值。你可以做这样的事情。

这是一个代码框

import React from "react";
import ReactDOM from "react-dom";

class App extends React.Component {
  constructor() {
    super();
    this.arr = [
      { type: "text", name: "state1" },
      { type: "password", name: "state2" }
    ];

    // set the state keys dynamically from this.arr
    this.state = this.arr.reduce((agg, item) => {
      agg[item.name] = "";
      return agg;
    }, {});
  }

  handleChange = event => {
    const {
      target: { name, value }
    } = event;

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

  renderInputs = () => {
    return this.arr.map((item, i) => (
      <div key={i}>
        <label>
          <input
            type={item.type}
            name={item.name}
            value={this.state[item.name]}
            onChange={this.handleChange}
          />
        </label>
      </div>
    ));
  };

  render() {
    const inputs = this.renderInputs();
    return <div>{inputs}</div>;
  }
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

希望这可以帮助 !


推荐阅读