简体   繁体   English

在JSX中显示状态列表

[英]Displaying state list in JSX

I have some simple code: 我有一些简单的代码:

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"));

Working example here . 这里的工作示例。

When I click the button, the letter 'd' should be added to the letters in state. 当我单击按钮时,字母'd'应该添加到状态中的letters This works as intended. 这按预期工作。 However, the letters do not update on the page as one would expect when state changes. 但是,当状态发生变化时,字母不会在页面上更新。

It's worth noting that: 值得注意的是:

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

or: 要么:

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

do update the page as expected. 按预期更新页面。

Why is this? 为什么是这样?

You need to replace the letter's state (the array), instead of mutating it ( working example ). 你需要替换字母的状态(数组),而不是改变它( 工作示例 )。 According to the react docs : Do Not Modify State Directly. 根据反应文档 :不要直接修改状态。

When you're converting the array to a string, the current string is different from the previous string because strings are immutable. 当您将数组转换为字符串时,当前字符串与前一个字符串不同,因为字符串是不可变的。 The array however stays the same array even if you add another item to it. 然而,即使您向其添加另一个项目,该阵列仍保持相同的阵列。

Example: 例:

 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 

Solution: create a new array from the old one. 解决方案:从旧数组创建一个新数组。

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

You have got an answer though. 你有答案。 Would like to explain it a bit further. 想进一步解释一下。

You are basically not changing the state ever. 你基本上没有改变状态。 And react only detects the changes in state. 而反应只能检测状态的变化。 Now tricky part is that you might be thinking that you are updating the array object and hence changing the state but that's not true. 现在棘手的部分是你可能会认为你正在更新数组对象,从而改变状态,但事实并非如此。 The original array reference is never changed in state and hence no change. 原始数组引用永远不会在状态中更改,因此不会更改。 So, to solve this in es6 you could use ... operator as follows in your addLetter declaration. 因此,要在es6中解决此问题,您可以在addLetter声明中使用...运算符,如下所示。

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

... operator basically clones the original object and is a short hand operator from es6 . ...运算符基本上克隆了原始对象,是es6的简写操作符。

You could use clone method as well eg Object.assign . 您也可以使用克隆方法,例如Object.assign

Hope it helps! 希望能帮助到你!

I've forked and fixed your code here: https://codesandbox.io/s/ywnmr47q8z 我在这里分叉并修复了你的代码: https//codesandbox.io/s/ywnmr47q8z

1) You have to mutate the new state 1)你必须改变新的状态

2) you have to call .join("") to build string from array. 2)你必须调用.join("")来从数组构建字符串。 now it is working 现在它正在运作

编辑ywnmr47q8z

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM