在JSX中显示状态列表

时间:2018-04-30 18:52:08

标签: javascript reactjs

我有一些简单的代码:

class App extends React.Component {
  state = {
    letters: ["a", "b", "c"]
  };

  addLetter = () => {
    const { letters } = this.state;
    letters.push("d");
    this.setState({ letters });
  };

  render() {
    return (
      <div>
        <button onClick={this.addLetter}>Click to add a letter</button>
        <h1>letters: {this.state.letters}</h1>
      </div>
    );
  }
}

render(<App />, document.getElementById("root"));

工作示例here

单击按钮时,字母'd'应添加到letters处于状态。这按预期工作。但是,当状态发生变化时,字母不会在页面上更新。

值得注意的是:

<h1>letters: {this.state.letters.reduce((a, l) => a + l, "")}</h1>

或:

<h1>letters: {this.state.letters.toString()}</h1>

按预期更新页面。

为什么会这样?

3 个答案:

答案 0 :(得分:3)

你需要替换字母的状态(数组),而不是改变它(working example)。根据反应docs:不要直接修改状态。

当您将数组转换为字符串时,当前字符串与前一个字符串不同,因为字符串是不可变的。但是,即使您向其中添加了另一个项目,该数组也会保持相同的数组。

示例:

&#13;
&#13;
const a = [1, 2, 3];
const strA = a.toString();
a.push(4);
const strB = a.toString();

console.log(a === a); // true
console.log(strA === strB); // false
&#13;
&#13;
&#13;

解决方案:从旧数组中创建一个新数组。

addLetter = () => {
  const { letters } = this.state;
  this.setState({ letters: [...letters, 'd'] });
}; 

答案 1 :(得分:1)

你已经得到了答案。想进一步解释一下。

你基本上没有改变状态。而反应只能检测状态的变化。现在棘手的部分是你可能会认为你正在更新数组对象,从而改变状态,但事实并非如此。原始数组引用永远不会在状态中更改,因此不会更改。因此,要在es6中解决此问题,您可以在addLetter声明中使用...运算符。

addLetter = () => {
    const { letters } = this.state;
    letters.push("d");
    this.setState({ letters:[...letters] });
  };

...运算符基本上克隆了原始对象,是来自es6的简写运算符。

您也可以使用克隆方法,例如Object.assign

希望它有所帮助!

答案 2 :(得分:0)

我在这里分叉并修复了您的代码:https://codesandbox.io/s/ywnmr47q8z

1)你必须改变新的状态

2)你必须调用.join("")来从数组构建字符串。现在它正在运作

Edit ywnmr47q8z