【问题标题】:React does not re-render component after setStateReact 在 setState 之后不会重新渲染组件
【发布时间】:2019-08-25 17:35:39
【问题描述】:

我有一个奇怪的问题。 state 已更新,但不会重新渲染组件。当我按下按钮Add Hi All 时,必须添加额外的<p>Hi All</p>。但我没有在屏幕上看到它们。

有趣的是,如果我将new_row 更改为这样的 1 元素数组

var new_row = [<p key = {key_number + "d"}> Hi all!</p>];

然后将使用parag_s.concat(new_row) 而不是parag_s.push(new_row) 一切正常。 state.ps 数组的包含在两种变体中似乎完全相同,但是当我使用时不知何故 parag_s.push(new_row) 重新渲染过程未启动。
这就是为什么我觉得我做错了什么。你可以帮帮我吗?为什么下面的代码不起作用?

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

class App extends React.Component {
    render() {
        return (
            <BlablablaComponent/>
        );
    }
}

class BlablablaComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            ps: [],
            keyNumber: 1
        }
        this.addRow = this.addRow.bind(this);
    }

    addRow() {
        var parag_s = this.state.ps;
        var key_number = this.state.keyNumber;
        key_number = key_number + 1;
        var new_row = <p key = {key_number + "d"}> Hi all!</p>;
        parag_s.push(new_row);
        var new_state = {ps: parag_s, keyNumber: key_number};
        this.setState(new_state);
   }

    render() {
        return (
            <div>
                {this.state.ps}
                <button type="button" onClick = {this.addRow} >Add Hi All</button> 
            </div>
        );
    }
}

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

【问题讨论】:

  • 不推荐在渲染函数中改变状态。也很容易导致死循环(change state -> render -> change state -> render...)
  • @Cristy 但我不会更改渲染函数内的状态。我为此使用 addRow。在渲染中,我只读取了 this.state.ps 属性(据我所知,它是 React 对象的数组)。请您再解释一下好吗?

标签: javascript reactjs setstate


【解决方案1】:

setState 对数组执行浅比较,当您 push 进入数组时,实例不会改变,因此 React 不会看到变化。当您使用concat 时,将返回一个新的数组实例。

您可以使用扩展运算符而不是 concat

 setState({
   key_number,
   parag_s: [...parag_s, new_row]
 })

【讨论】:

  • @James 非常感谢!当你改变状态但 React 看不到它时,你能再举几个例子吗?
  • @BlackBeard setState 是一个复杂的过程,如果您想了解更多关于它的工作原理,我只能为您指明docs 的方向。
猜你喜欢
  • 2019-01-24
  • 2021-04-28
  • 2020-08-08
  • 2020-02-18
  • 2017-11-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-10
  • 1970-01-01
相关资源
最近更新 更多