React 不会重新渲染

Posted

技术标签:

【中文标题】React 不会重新渲染【英文标题】:React does not re-render 【发布时间】:2016-05-09 00:14:01 【问题描述】:

我有带排序功能的 React 类 (List) 和简单元素的 React 类 (Elem)。如果排序功能启动,它将对状态数组中的元素进行排序并重新渲染列表,但保持不变,尽管状态数组已更改。代码:

var Elem = React.createClass(
    getInitialState() 
        var elem_name = this.props.name;
        return 
            name: elem_name
        
    ,
    render() 
        return <div>this.state.name</div>;
    
);

var List = React.createClass(
    getInitialState() 
        return 
            received: false,
            arr: null
        
    ,
    receiving() 
        this.setState(
            received: true,
            arr: [1, 2, 3, 4, 5]
        );
    ,
    sorting(type) 
        var self = this;
        return function() 
            function sort_func() 
                //sorting...
            
            var main_arr = self.state.arr;
            main_arr.sort(sort_func);
            self.setState(
                arr: main_arr
            )
        
    ,
    render() 
        if(this.state.received) 
            var all_elems = [];
            this.state.arr.forEach(function(elem) 
                all_elems.push(<Elem name=elem>);
            );
            return <div>
                <button onClick=this.sorting>Sort</button>
                all_elem
            </div>
        
        else 
            this.receiving();
            return <div>Empty</div>;
        
    
);

例如排序后的数组是[5, 4, 3, 2, 1]。最初的 html 页面是

<div>1</div><div>2</div>...<div>5</div>;

但排序后的 HTML 页面保持不变,虽然数组的状态发生了变化。

【问题讨论】:

给你的元素一个独特的key属性。除非你需要修改它,否则避免将 prop 复制到 state (props.name => state.name) 看起来你正在使用 ES6!请使用arrow functions 而不是self = this 【参考方案1】:

我已经重构了你的代码,因为在你的版本中有几个错误

    Elem 你不需要使用state, 您可以在getInitialState 中将初始数据添加到arr,而不是使用this.receiving();,并避免在render 方法中使用if/else 用`.map代替this.state.arr.forEach更合适

    用arrow functions代替var self = this;

    var Elem = React.createClass(
      render() 
        return <div> this.props.name </div>;
      
    );
    
    var List = React.createClass(
      getInitialState() 
        return 
          received: false,
          arr: [1, 2, 3, 4, 5]
        
      ,
    
      sorting(type) 
        this.setState(
          received: !this.state.received,
          arr: this.state.arr.sort((a, b) => 
            return !this.state.received ? b - a : a - b;
          )
        )
      ,
    
      render() 
        var elements = this.state.arr.map((elem, index) => 
          return <Elem name=elem key=index />
        );
    
        return <div>
          <button onClick=this.sorting>Sort</button>
           elements 
        </div>;
      
    );
    

Example

【讨论】:

以上是关于React 不会重新渲染的主要内容,如果未能解决你的问题,请参考以下文章

React:setState 不会导致重新渲染?

React redux和React路由器,链接更改不会重新渲染视图[重复]

即使在调用 setState 之后,React.js 子状态也不会重新渲染?

React 子组件不会在其状态更改时重新渲染

状态更改时不会重新渲染 React-typing-animation

在 redux 中调度存储变量时,React 组件不会重新渲染