【问题标题】:React functional component doesnt rerender when changing props passed as an array更改作为数组传递的道具时,React 功能组件不会重新渲染
【发布时间】:2018-09-20 15:37:31
【问题描述】:

当我将数组作为道具传递并更改数组的值时,我的功能组件不会重新呈现。

https://codesandbox.io/s/5ym4vkrnnk

import React, { PureComponent, Fragment } from "react";
import ReactDOM from "react-dom";

const SomeFunctionalComponent = props => {
  return <span>{props.array[0]}</span>;
};

class App extends PureComponent {
  state = {
    array: [1, 2, 3]
  };
  increase = () => {
    var array = this.state.array;
    array[0] = array[0] + 1;
    this.setState({ array: array });
    console.log(this.state.array);
  };
  render() {
    return (
      <Fragment>
        <button onClick={this.increase}>Increase</button>
        <SomeFunctionalComponent array={this.state.array} />
      </Fragment>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

我的问题:

  1. 为什么会这样?
  2. 我该如何改变呢?

提前感谢您的帮助!

【问题讨论】:

  • 您正在更改数组中的值,但对数组的引用保持不变。由于react 在您调用increase() 之前和之后看到相同的对象引用,因此它实际上并不知道发生了什么变化。您应该尝试使用纯函数和不变性。

标签: javascript reactjs


【解决方案1】:

永远不要直接改变状态

您直接在代码中更改状态,因此更改不会得到反映。数组成为 this.state.array 的引用,这会导致不希望的突变。

import React, { PureComponent, Fragment } from "react";
import ReactDOM from "react-dom";

const SomeFunctionalComponent = props => {
  return <span>{props.array[0]}</span>;
};

class App extends PureComponent {
  state = {
    array: [1, 2, 3]
  };
  increase = () => {
    var array = [...this.state.array];
    array[0] = array[0] + 1;
    this.setState({ array: array });
    console.log(this.state.array);
  };
  render() {
    return (
      <Fragment>
        <button onClick={this.increase}>Increase</button>
        <SomeFunctionalComponent array={this.state.array} />
      </Fragment>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

【讨论】:

  • 您可以添加 array 成为对 this.state.array 的引用,这会导致不需要的突变
  • 非常感谢,看来我缺乏一些基本的javascript知识...我在写的时候想:var array = this.state.array;数组[0] = 数组[0] + 1;我将此 .state.array 的值复制到另一个变量中,然后更改它,而不是更改引用?
  • 附带说明,展开语法会创建浅拷贝。使用这个简单的代码就可以了,但是如果你改变了新数组的嵌套属性,你就会改变原来的。
  • @VelimirTchatchevsky 谢谢我已将其添加到答案中
猜你喜欢
  • 2023-02-15
  • 1970-01-01
  • 2021-12-22
  • 2021-07-13
  • 1970-01-01
  • 2021-09-01
  • 2021-12-04
  • 2021-01-14
  • 2021-10-10
相关资源
最近更新 更多