【问题标题】:Why react doesn't call render when state is changed?为什么当状态改变时反应不调用渲染?
【发布时间】:2023-04-07 07:02:02
【问题描述】:

当状态改变时,我遇到了自动重新渲染视图的问题。 状态已更改,但未调用 render()。但是当我打电话给this.forceUpdate() 时,一切都很好,但我认为这不是最好的解决方案。 有人可以帮我吗?

class TODOItems extends React.Component {

constructor() {
    super();

    this.loadItems();
}

loadItems() {
    this.state = {
        todos: Store.getItems()
    };
}

componentDidMount(){
    //this loads new items to this.state.todos, but render() is not called
    Store.addChangeListener(() => { this.loadItems(); this.forceUpdate(); });
}

componentWillUnmount(){
    Store.removeChangeListener(() => { this.loadItems(); });
}

render() {

    console.log("data changed, re-render");
    //...
}}

【问题讨论】:

    标签: javascript reactjs flux


    【解决方案1】:

    你不应该直接改变this.state。你应该使用this.setState 方法。

    更改loadItems

    loadItems() {
        this.setState({
            todos: Store.getItems()
        });
    }
    

    More in react docs

    【讨论】:

      【解决方案2】:

      当您声明初始状态时,您应该使用构造函数中的this.state = {};(就像在您的loadItems() 方法中一样)。如果要更新项目,请使用this.setState({})。例如:

      constructor() {
          super();
      
          this.state = {
              todos: Store.getItems()
          };
      }
      
      reloadItems() {
          this.setState({
              todos: Store.getItems()
          });
      }
      

      并更新您的componentDidMount

      Store.addChangeListener(() => { this.reloadItems(); });
      

      【讨论】:

      • this.state 永远不应该直接变异。
      • @JCD 我的错,我来自 React Native,this.state = {} 可用于从构造函数声明初始状态。
      • @JCD 实际上,根据React docs,这是完全合法的,或者至少在那里使用过(参见第二个代码块中的 ES6 类)
      • 是的,当使用 ES6 类时,您可以直接在构造函数中分配状态。一旦构造函数完成,不要直接改变它,而是使用setState
      • 谢谢大家,我认为当我在构造函数中将它设置为普通对象时,它会在任何地方设置(更改)相同的方式。
      【解决方案3】:

      在您的组件中,每当您直接操作状态时,您都需要使用以下内容:

      this.setState({});
      

      完整代码:

      class TODOItems extends React.Component {
      
      constructor() {
          super();
      
          this.loadItems();
      }
      
      loadItems() {
        let newState = Store.getItems();
          this.setState = {
      
              todos: newState
          };
      }
      
      componentDidMount(){
          //this loads new items to this.state.todos, but render() is not called
          Store.addChangeListener(() => { this.loadItems(); this.forceUpdate(); });
      }
      
      componentWillUnmount(){
          Store.removeChangeListener(() => { this.loadItems(); });
      }
      
      render() {
      
          console.log("data changed, re-render");
          //...
      }}
      

      【讨论】:

        猜你喜欢
        • 2017-03-25
        • 2019-11-19
        • 2023-01-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-22
        • 2017-12-27
        • 1970-01-01
        相关资源
        最近更新 更多