在组件更改时不重新渲染React组件

时间:2019-04-25 10:28:48

标签: javascript reactjs

我有一个react组件,可以在页面加载时正确呈现,但是当props更改时,不会重新呈现。下面的console.log(list)表示正在调用render(),并且列表数组包含正确的数据,但是该页面不再重新呈现。

如果我在componentDidUpdate()中添加setState,那么我将得到一个无限循环。

是什么原因造成的?

这是调用siteList的应用程序。

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

import Filters from './Components/List/Filters.js';
import SiteList from './Components/List/SiteList.js';


class App extends React.Component {
  constructor() {
    super();

    this.state = {
      sites : [{ _id: {}, urpn: 0, wifi: false, fibre: false, location: { 'coordinates' : [0, 0] } }], 
      filters: {Properties: false, Customers: false, Coverage: false, Network: false, Fibre50: false, Fibre200: false, Fibre500: false  }, 
      page: 1, 
      pageSize: 25,
    };

  }

  componentDidMount = () => {
    this.getSites();
  };

  setSearch = (data) => {

    var state = this.state;
    state.search = data;
    this.setState(state);

    console.log( "state search" + this.state.search );

    this.getSites();
  }

  setType = (data) => {
    var filters = this.state.filters;

    if(this.state.filters[data] == true){
      filters[data] = false;
    }else{
      filters[data] = true;
    }

    var state = this.state;
    state.filters = filters;
    this.setState(state);

    this.getSites();
  };

  getSites = () => {
    if (typeof controller !== "undefined") {
      controller.abort();
    }

    if ("AbortController" in window) {
      var controller = new AbortController;
      var signal = controller.signal;
    }

    var url = '/wisp/public/api/sites?';

    if(this.state.filters){
      var filtersString = JSON.stringify(this.state.filters);
      url = url + '&filters=' + filtersString;
    }

    if(this.state.search){
      //var searchString = JSON.stringify(this.state.search);
      var searchString = this.state.search;
      url = url + '&search=' + searchString;
    }

    if(this.state.page){
      var pageString = JSON.stringify(this.state.page);
      var pageSizeString = JSON.stringify(this.state.pageSize);
      url = url + '&page=' + pageString;
      url = url + '&pageSize=' + pageSizeString;
    }


    this.setState({loading: true}, () => {
      fetch(url, {signal})
      .then(response => response.json())
      .then(data => {
        this.setState({
          sites : data.sites, 
          count : data.count, 
        }
        , () => {
          console.log("this.state.sites");
          console.log(this.state.sites);
          this.setState({loading: false});
        });
      });
    }); 

  };

  render() {
    return (
      <section className="section list">
        <Filters filters={this.state.filters} setType={this.setType} setSearch={this.setSearch} runexport={this.runexport} />
        <SiteList
          sites={this.state.sites}
          passiveSites={this.state.passiveSites}
          activeSites={this.state.activeSites}
        />

      </section>
    );
  }
}

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

这是网站列表

export default class SiteList extends React.Component {

  render() {

    const list = this.props.sites.map((item, i) => {
        return <div key={i} className="box">
                <SiteForm
                  item={item}
                />
              </div>
    });

    console.log(list); 

    return (
      <div className="container">
          {list}
      </div>
    );
  }

}

站点表单只是一个json.Stringify打印,问题仍然存在。我无法在代码上创建最低工作版本,因为它依赖于私有API。这和我可以做的代码库一样小。

1 个答案:

答案 0 :(得分:0)

我的问题最终与网站表单有关,我的解决方案是添加

componentDidUpdate(previousProps, previousState) {

    if (previousProps.item !== this.props.item) {
        var temp = _.cloneDeep(this.props.item);
        temp.components = undefined;
        this.setState({item: temp });
    }

    if (previousProps.components !== this.props.components) {
        var temp2 = []; 
        temp2 = _.cloneDeep(this.props.item.components); 
        this.setState({components: temp2 }); 
    }
}

我感觉克隆克隆的东西是过大的杀伤力,但是这样更整洁。