如何阻止多次重新渲染组件?

时间:2019-07-31 20:05:36

标签: reactjs

我有一个包含一些其他组件的组件,这些组件依赖于减速器状态。每当我在组件中运行操作时,它都会多次渲染。最后两个渲染器完全在render函数中,我不知道会发生这种情况。 我尝试使用chrome中的react dev工具跟踪渲染,但不确定为什么或如何发生。一切似乎合乎逻辑,它会运行需要运行的内容,然后在之后再放弃两次。

由于没有任何我可以依赖的变量,所以我不能使用应该组件更新。

还有其他人有与此相关的问题吗?如果是这样,您如何解决这个问题?

主要组成部分


class LoadTable extends React.Component {
    constructor(props) {
        super(props);
    }
    componentDidMount() {
        this.setState({ fetchInProgress: true });
        const getJobsPromise = this.props.getJobs(null, null);
        const getJobNamesPromise = this.props.getJobNames();

        Promise.all([getJobsPromise, getJobNamesPromise])
            .then(([jobsRes, jobNamesRes]) => {
                if (jobsRes.results.response.length > 0) {
                    var initStart = jobsRes.results.response[0].ID;
                    var initEnd = jobsRes.results.response[jobsRes.results.response.length - 1].ID;
                    var newStart = initStart;
                    var newEnd = initEnd;
                    var snewStart = null;
                    var snewEnd = null;
                    var sinitStart = null;
                    var sinitEnd = null;
                    var filterOn = false;
                    var searchOn = false;
                    var pagMax = (Math.ceil(jobsRes.results.response.length / 10) > 0) ? Math.ceil(jobsRes.results.response.length) / 10 : 0;
                    pagMax = pagMax + 1;
                    this.props.dispatch({ type: jobConstants.JOB_SUCCESS, newStart, newEnd, initStart, initEnd, pagMax, snewStart, snewEnd, sinitStart, sinitEnd, filterOn, searchOn });
                }                
                this.setState({                    
                    fetchInProgress: false,
                    panelOpen: false,
                    data: jobsRes.results.response || [],                    
                    jobNames: jobNamesRes.results.response || [],
                });
            });
}
    runLog(id) {
        this.props.runLog(id);
    }
    openRunLog(logs) {
        this.props.findOutput(logs);
    } 

    handleJobName(e) {
        if (e.target.value === 'default') {
            this.setState({
                selectedJName: 0
            });
        } else {
            this.setState({
                selectedJName: e.target.value
            });
        }
    }    

    clearSearch() {
        this.setState({ fetchInProgress: true });
        this.props.getJobs(null, null) 
            .then((res) => {
                this.setState({
                    data: res.results.response || [],    
                    fetchInProgress: false,
                    searchOn: false,
                    sort: {
                        column: null,
                        direction: 'desc',
                    }
                })
            });
    }
    handleSearch(e) {
        const { name, value } = e.target;  
        const { SearchEndLoc, SearchStrtLoc, SearchIntStrt, SearchIntEnd, EndLoc, StartLoc  } = this.props;
        this.setState({ [name]: value });       

        var initStart;
        var initEnd;
        var newStart;
        var newEnd;
        var pagMax;
        var snewStart;
        var snewEnd;
        var sinitStart;
        var sinitEnd;
        var searchOn;
        var filterOn;
        this.setState({ fetchInProgress: true });       
        if (value.length < 1) {            
            searchOn = false;
            this.props.getJobs(EndLoc, StartLoc)
                .then((res) => {
                     initStart = this.props.initStart;
                     initEnd = this.props.initEnd;
                     newStart = StartLoc;
                     newEnd = EndLoc;
                     snewStart = null;
                     snewEnd = null;
                     sinitStart = null;
                     sinitEnd = null;
                     filterOn = false;
                     pagMax = (Math.ceil(res.results.response.length / 10) > 0) ? Math.ceil(res.results.response.length / 10) : 0;
                     pagMax = pagMax + 1;
                    this.props.dispatch({ type: jobConstants.JOB_SUCCESS, newStart, newEnd, initStart, initEnd, pagMax, snewStart, snewEnd, sinitStart, sinitEnd,searchOn, filterOn});
                    this.setState({
                        data: res.results.response || [], 
                        fetchInProgress: false,                        
                        Search: '',
                        panelOpen: false,
                        searchRNames: [],
                        sort: {
                            column: null,
                            direction: 'desc'                           
                        }
                    }) 
                });
        } else {   
        searchOn = true;    
        this.props.doSearch(value, SearchEndLoc, SearchStrtLoc)
                .then((res) => {
                    if (res.results.response.length > 0) {
                        sinitStart = SearchIntStrt === null || SearchIntStrt === undefined ? res.results.response[0].ID : SearchIntStrt;
                        sinitEnd = SearchIntEnd === null || SearchIntEnd === undefined ? res.results.response[res.results.response.length - 1].ID : SearchIntEnd;
                        snewStart = sinitStart;
                        snewEnd = sinitEnd;    
                        newStart = null;
                        newEnd = null;
                        initStart = null;
                        initEnd = null;
                        filterOn = false;
                        pagMax = (Math.ceil(res.results.response.length / 10) > 0) ? Math.ceil(res.results.response.length / 10) : 0;
                        pagMax = pagMax + 1;                         
                        this.props.dispatch({ type: jobConstants.JOB_SUCCESS, newStart, newEnd, initStart, initEnd, pagMax, snewStart, snewEnd, sinitStart, sinitEnd, searchOn, filterOn});
                    }
                        this.setState({
                            data: res.results.response || [],                               
                            searchRNames: res.results.response || [],                           
                            SearchOn: searchOn,
                            filterOn: filterOn,
                            panelOpen: true,
                            fetchInProgress: false,
                            Search: value,                            
                            sort: {
                                column: null,
                                direction: 'desc',
                            }
                    })

                });
        }
    }    
    onChangePage(changePage) {      
        this.setState({ pageOfItems: changePage.pageOfItems });
        if (changePage.searchOn === true) {
            this.updateOnSearch(changePage);
        }
        if (changePage.filterOn === true) {
            this.updateOnFilter(changePage);
        }
        if ((changePage.searchOn === false) && (!changePage.filterOn === false)) {
            this.updateOnRegular(changePage);
        }
    }
    updateOnSearch(changePage) {             
        var newStart = changePage.newStart;
        var newEnd = changePage.newEnd;
        var initStart = changePage.initStart;
        var initEnd = changePage.initEnd;
        var snewStart = changePage.snewStart;
        var snewEnd = changePage.snewEnd;
        var sinitStart = changePage.sinitStart;
        var sinitEnd = changePage.sinitEnd;
        var searchOn = true;
        var filterOn = false;
        var pagMax;

        if ((changePage.snewStart === null) && (changePage.snewEnd === null)) {            
            this.setState({ fetchInProgress: true });
            this.props.doSearch(this.state.Search, changePage.newEnd, changePage.newStart)
                .then((res) => {
                    if (res.results.response.length > 0) {
                        sinitStart = res.results.response[0].ID;
                        sinitEnd = res.results.response[res.results.response.length - 1].ID;
                        snewStart = changePage.sinitStart;
                        snewEnd = changePage.sinitEnd;
                        pagMax = (Math.ceil(res.results.response.length / 10) > 0) ? Math.ceil(res.results.response.length / 10) : 0;
                        pagMax = pagMax + 1;
                        this.props.dispatch({ type: jobConstants.JOB_SUCCESS, newStart, newEnd, initStart, initEnd, pagMax, snewStart, snewEnd, sinitStart, sinitEnd, searchOn, filterOn });
                    }
                    this.setState({
                        fetchInProgress: false,
                        searchOn: searchOn,
                        filterOn: filterOn,
                        panelOpen: true,
                        pageOfItems: res.results.response || [],
                        sort: {
                            column: null,
                            direction: 'desc',
                        }
                    })
                });
        }
        if ((changePage.snewStart !== null) && (changePage.snewEnd !== null)) {
            this.setState({ fetchInProgress: true });
            this.props.doSearch(this.state.Search, changePage.snewEnd, changePage.snewStart)
                .then((res) => {
                    if (res.results.response.length > 0) {
                        snewStart = res.results.response[0].ID;
                        snewEnd = res.results.response[res.results.response.length - 1].ID;
                        pagMax = (Math.ceil(res.results.response.length / 10) > 0) ? Math.ceil(res.results.response.length / 10) : 0;
                        pagMax = pagMax + 1;
                        searchOn = false;                        
                        this.props.dispatch({ type: jobConstants.JOB_SUCCESS, newStart, newEnd, initStart, initEnd, pagMax, snewStart, snewEnd, sinitStart, sinitEnd, searchOn, filterOn });
                    }
                    this.setState({
                        data: res.results.response || [],
                        fetchInProgress: false,
                        searchOn: searchOn,
                        filterOn: filterOn,
                        panelOpen: true,
                        pageOfItems: res.results.response || [],
                        sort: {
                            column: null,
                            direction: 'desc',
                        }
                    })

                });
        }      
    }
    updateOnFilter(changePage) {
        const { selectedDRan, selectedDStart, selectedDEnd, selectedJName} = this.state;
        var newStart = changePage.newStart;
        var newEnd = changePage.newEnd;
        var initStart = changePage.initStart;
        var initEnd = changePage.initEnd;
        var snewStart = changePage.snewStart;
        var snewEnd = changePage.snewEnd;
        var sinitStart = changePage.sinitStart;
        var sinitEnd = changePage.sinitEnd;
        var searchOn = false;
        var filterOn = true;
        var pagMax;

        if ((snewStart === null) && (snewEnd === null)) {
            this.setState({ fetchInProgress: true });
            this.props.filterJobs(selectedJName, selectedDRan, selectedDStart, selectedDEnd, snewStart, snewEnd)
                .then((res) => {
                    if (res.results.response.length > 0) {
                        sinitStart = res.results.response[0].ID;
                        sinitEnd = res.results.response[res.results.response.length - 1].ID;
                        snewStart = changePage.sinitStart;
                        snewEnd = changePage.sinitEnd;
                        pagMax = (Math.ceil(res.results.response.length / 10) > 0) ? Math.ceil(res.results.response.length / 10) : 0;
                        pagMax = pagMax + 1;
                        searchOn = false;
                        this.props.dispatch({ type: jobConstants.JOB_SUCCESS, newStart, newEnd, initStart, initEnd, pagMax, snewStart, snewEnd, sinitStart, sinitEnd, searchOn, filterOn });
                    }
                    this.setState({
                        fetchInProgress: false,
                        searchOn: searchOn,
                        filterOn: filterOn,
                        panelOpen: true,
                        pageOfItems: res.results.response || [],
                        sort: {
                            column: null,
                            direction: 'desc',
                        }
                    })
                });
        }
        if ((snewStart !== null) && (snewEnd !== null)) {
            this.setState({ fetchInProgress: true });
            this.props.filterJobs(selectedJName, selectedDRan, selectedDStart, selectedDEnd, snewStart, snewEnd)
                .then((res) => {
                    if (res.results.response.length > 0) {
                        snewStart = res.results.response[0].ID;
                        snewEnd = res.results.response[res.results.response.length - 1].ID;
                        pagMax = (Math.ceil(res.results.response.length / 10) > 0) ? Math.ceil(res.results.response.length / 10) : 0;
                        pagMax = pagMax + 1;
                        searchOn = false;
                        this.props.dispatch({ type: jobConstants.JOB_SUCCESS, newStart, newEnd, initStart, initEnd, pagMax, snewStart, snewEnd, sinitStart, sinitEnd, searchOn, filterOn });
                    }
                    this.setState({
                        data: res.results.response || [],
                        fetchInProgress: false,
                        searchOn: searchOn,
                        filterOn: filterOn,
                        panelOpen: true,
                        pageOfItems: res.results.response || [],
                        sort: {
                            column: null,
                            direction: 'desc',
                        }
                    })
                });
        }
    }
    updateOnRegular(changePage) {        
        var newStart = changePage.newStart;
        var newEnd = changePage.newEnd;
        var initStart = changePage.initStart;
        var initEnd = changePage.initEnd;
        var snewStart = changePage.snewStart;
        var snewEnd = changePage.snewEnd;
        var sinitStart = changePage.sinitStart;
        var sinitEnd = changePage.sinitEnd;
        var searchOn = changePage.searchOn;
        var filterOn = changePage.filterOn;
        var pagMax;

        if ((changePage.newStart !== null) && (changePage.newEnd !== null)) {
            this.setState({ fetchInProgress: true });
            this.props.getJobs(changePage.newEnd, changePage.newStart)
                .then((res) => {
                    if (res.results.response.length > 0) {
                        newStart = res.results.response[0].ID;
                        newEnd = res.results.response[res.results.response.length - 1].ID;
                        snewStart = null;
                        snewEnd = null;
                        sinitStart = null;
                        sinitEnd = null;
                        pagMax = (Math.ceil(res.results.response.length / 10) > 0) ? Math.ceil(res.results.response.length / 10) : 0;
                        pagMax = pagMax + 1;
                        this.props.dispatch({ type: jobConstants.JOB_SUCCESS, newStart, newEnd, initStart, initEnd, pagMax, snewStart, snewEnd, sinitStart, sinitEnd, searchOn, filterOn });
                    }
                    this.setState({                        
                        fetchInProgress: false,
                        pageOfItems: res.results.response || [],
                        sort: {
                            column: null,
                            direction: 'desc',
                        }
                    })
                });
        }
    }

    onFilterChange() {        
        const { selectedDRan, selectedDStart, selectedDEnd, selectedJName,jobNames } = this.state;
        this.setState({ fetchInProgress: true, filterOn: true });
        var filterOn = true;
        var searchOn = false;
        var filterCheck = this.state.filterCheck;
        var initEnd;
        var initStart
        var newStart;
        var newEnd;
        var pagMax;

        if (filterCheck < 1) {
            this.props.filterJobs(selectedJName, selectedDRan, selectedDStart, selectedDEnd, null, null)
                .then((res) => {
                    if (res.results.response.length > 0) {
                         initStart = res.results.response[0].ID;
                         initEnd = res.results.response[res.results.response.length - 1].ID;
                         newStart = initStart;
                         newEnd = initEnd;
                         pagMax = (Math.ceil(res.results.response.length / 10) > 0) ? Math.ceil(res.results.response.length) / 10 : 0;
                         pagMax = pagMax + 1;
                        this.props.dispatch({ type: jobConstants.JOB_SUCCESS, newStart, newEnd, initStart, initEnd, pagMax, selectedDRan, selectedDStart, selectedDEnd, jobNames, searchOn, filterOn });
                    }                    
                    filterCheck = filterCheck + 1; 
                    this.setState({
                        data: res.results.response || [],
                        fetchInProgress: false,
                        filterOn: filterOn,
                        searchOn: searchOn,
                        filterCheck: filterCheck,
                        panelOpen: true,                        
                        sort: {
                            column: null,
                            direction: 'desc',
                        }
                    })
                });
        } else {
            this.props.filterJobs(selectedJName, selectedDRan, selectedDStart, selectedDEnd, this.props.snewEnd, this.props.snewStart)
                .then((res) => {
                    if (res.results.response.length > 0) {
                        newStart = res.results.response[0].ID;
                        newEnd = res.results.response[res.results.response.length - 1].ID;
                        pagMax = (Math.ceil(res.results.response.length / 10) > 0) ? Math.ceil(res.results.response.length / 10) : 0;
                        pagMax = pagMax + 1;
                        this.props.dispatch({ type: jobConstants.JOB_SUCCESS, newStart, newEnd, initStart, initEnd, pagMax, selectedDRan, selectedDStart, selectedDEnd, jobNames, searchOn, filterOn });
                    }
                    filterCheck = filterCheck + 1;
                    this.setState({
                        data: res.results.response || [],
                        fetchInProgress: false,
                        filterOn: filterOn,
                        searchOn: searchOn,
                        panelOpen: true,
                        filterCheck: filterCheck,
                        pageOfItems: res.results.response || [],
                        sort: {
                            column: null,
                            direction: 'desc',
                        }
                    })
                });

        }

    }
    onFilterClear() {
        this.setState({ fetchInProgress: true });
        const getJobsPromise = this.props.getJobs(null, null);
        const getJobNamesPromise = this.props.getJobNames();

        Promise.all([getJobsPromise, getJobNamesPromise])
            .then(([jobsRes, jobNamesRes]) => {
                if (jobsRes.results.response.length > 0) {
                    var initStart = jobsRes.results.response[0].ID;
                    var initEnd = jobsRes.results.response[jobsRes.results.response.length - 1].ID;
                    var newStart = initStart;
                    var newEnd = initEnd;
                    var snewStart = null;
                    var snewEnd = null;
                    var sinitStart = null;
                    var sinitEnd = null;
                    var filterOn = false;
                    var searchOn = false;
                    var pagMax = (Math.ceil(jobsRes.results.response.length / 10) > 0) ? Math.ceil(jobsRes.results.response.length) / 10 : 0;
                    pagMax = pagMax + 1;
                    this.props.dispatch({ type: jobConstants.JOB_SUCCESS, newStart, newEnd, initStart, initEnd, pagMax, snewStart, snewEnd, sinitStart, sinitEnd, filterOn, searchOn });
                }
                this.setState({
                    fetchInProgress: false,
                    panelOpen: false,
                    data: jobsRes.results.response || [],
                    jobNames: jobNamesRes.results.response || [],
                });
            });
    }
    render() { 
               const { data, Search, pageOfItems, searchRNames, fetchInProgress, jobNames, selectedDRan, selectedDStart, selectedDEnd, selectedJName, panelOpen} = this.state; 
        const { jobRun } = this.props;       

        return(
        <div>
                {fetchInProgress ? (
                    <div className="row row-centered">
                            <p>Loading.....Please Wait</p>
                        </div>
                   </div>                   
                 ) : (
                    data.length < 0 ? ( 
                                           <div className="searchNoContent"><h3>No Data to Display at the moment</h3></div>
                    </div>
                  )  : (
                    <div className="row row-centered">                       
                        <div className="col-lg-12 col-md-12 col-sm-12 col-xs-12 col-centered">
                         {!IsEmpty(jobRun) && <Alert color="success">{jobRun}</Alert>}
                                        <div className="wrap-collabsible">
                                            <input id="collapsible" className="toggle tCheck" type="checkbox" value={panelOpen} onChange={this.handleCheckBox} checked={panelOpen} />
                                            <label htmlFor="collapsible" className="lbl-toggle">Filter/Search Jobs</label>
                                                <div className="collapsible-content">
                                                    <div className="content-inner">
                                                            <div id="Search" className="">
                                                                <div className="input-group">
                                                                    <Autocomplete
                                                                        getItemValue={(item) => item.Name}
                                                                        items={searchRNames}
                                                                        inputProps={{ className: 'form-control searchIte ms', placeholder: 'Search', name: 'Search', autoFocus: true }}
                                                                        value={Search}
                                                                        onSelect={(Search, item) => this.setState({ Search, searchRNames: item })}
                                                                        renderItem={(item, isHighlighted) =>
                                                                            <div></div>
                                                                        }
                                                                        onChange={this.handleSearch}
                                                                    />
                                                                </div>
                                                            </div>
                                                            <div className="tableFilter">
                                                                <div className='filterArea'>

                                                                    <div className='filterBody'>
                                                                        <p className='filterLabel'>Job Name: </p>
                                                                <select defaultValue={selectedJName} className='itemList' onChange={this.handleJobName}>
                                                                            <option key='0' value='0'>--Select--</option>
                                                                    {jobNames.map((jbName) => <option key={jbName.ID} value={jbName.ID}>{jbName.Name}</option>)}                                                                        </select>                                                                            <button type="button" className="btn btn-success jobFilterBtn " onClick={()=>this.onFilterChange()}>Filter Jobs</button>                                                                            <button type="button" className="btn btn-danger jobFilterBtn " onClick={() => this.onFilterClear()}>Clear Filter</button>
                                                                        </div>
                                                                        </div>
                                                                     </div>
                                                              </div>
                                                            </div>                                                
                                                    </div>
                                        </div>
                                        <table className="table table-striped">
                                            <thead>
                                                <tr>
                                                    <th className="columnHeader" onClick={() => this.doSort('name')}>Name</th>
                                                    <th className="columnHeader" onClick={() => this.doSort('date')}>Date Ran</th>
                                                    <th className="columnHeader" onClick={() => this.doSort('job')}>Job</th>
                                                    <th className="columnHeader" onClick={() => this.doSort('start')}>Start</th>
                                                    <th className="columnHeader" onClick={() => this.doSort('end')}>End</th>
                                                    <th className="columnHeader" onClick={() => this.doSort('status')}>Status</th>
                                                    <th></th>
                                                    <th></th>
                                                    <th></th>
                                                </tr>
                                            </thead>
                                            <tbody>
                                                {
                                                    pageOfItems.map(dt => {
                                                        return (                                                            
                                                            </tr>
                                                        );
                                                    })
                                                }
                                            </tbody>
                                   </table>  
                             <BOPagination items={data} onChangePage={this.onChangePage.bind(this)} />
                         </div>                                   
                   </div>                
                       ))}
               </div> 
               );
}
}

0 个答案:

没有答案