2017-08-18 155 views
0

我一直在研究一個小的待辦事項應用程序來學習,並讓我的頭繞過一些反應。一切都按計劃進行,直到我開始完成應用程序的完成部分。我試圖解決的問題可能非常簡單,但是,我似乎無法將自己的頭圍繞在發生的事情上。我想要做的是調用我的createCompletedList方法,以便我可以創建所有已完成的項目。儘管當在componentDidUpdate方法中調用該方法時,它會創建使瀏覽器崩潰的無限循環。有沒有什麼辦法可以叫做createCompletedList這種方法是安全的?componentDidUpdate導致無限循環

任何形式的建議或信息將不勝感激。


import React, { Component } from "react"; 

class Completed extends Component { 
    constructor(props) { 
    super(props); 
    console.log(props); 
    this.state = { 
     completedItems: [] 
    }; 

    this.checkIndex = this.checkIndex.bind(this); 
    this.createCompletedList = this.createCompletedList.bind(this); 
    } 

    checkIndex(event) { 
    console.log("index value is " + this.props.indexValue); 
    } 

    createCompletedList() { 
    const completedIndex = this.props.indexValue; 
    const completedArray = this.state.completedItems; 

    if (completedIndex) { 
     completedArray.push(this.props.arrayItems[completedIndex]); 
     this.setState(prevState => { 
     return { completedItems: completedArray }; 
     }); 
    } 

    console.log(this.state.completedItems); 
    } 

    componentDidUpdate() { 
    this.createCompletedList(); 
    } 

    render() { 
    let completedArray = this.state.completedItems; 

    const retrieveList = completedArray.map((elm, index, arr) => { 
     return (
     <div className="check-list-row checked" key={index}> 
      {elm} 
     </div> 
    ); 
    }); 
    return (
     <div 
     className={this.props.isTaskChecked ? "completed-container" : "hide"}> 
     <div className="completed-row"> 
      <h1>Completed</h1> 
     </div> 
     <div> 
      {retrieveList} 
     </div> 
     </div> 
    ); 
    } 
} 
export default Completed; 
+1

你不應該在'componentDidUpate'函數中使用'setState'函數(並且你有一個使用'setState'函數的函數的調用)。 – Dekel

+0

@愛德華如果你在渲染後立即調用你的'createCompletedList()', – abdul

+0

@abdul不幸的是,這也會導致無限循環。 –

回答

0

調用this.setState()將始終導致更新。您可以使用shouldComponentUpdate(nextProps, nextState)來確定是否實際更新。默認情況下,此方法始終返回true。如果您不想更新,請將nextState.completedItemsthis.state.completedItems進行比較,並返回false

+1

謝謝!這解決了我的問題。 –

0

不要在componentDidUpdate方法更新狀態。

如果您不想在此方法中更新您的狀態,您必須首先比較當前狀態與您的prev狀態。

componentDidUpdate(prevProps, prevState) { 
if(JSON.stringify(prevState) !== JSON.stringify(this.state)) { 
    ///your code.... 
} 


} 

或者比較它的另一個函數或庫如lodash。

+0

嗨artem,即時通訊想知道這種對象比較是否有效,即如果狀態包含函數。 –

+0

@J一個Ciołek狀態中的第一個參數如果不是對象,則是函數 - 更新器,它有助於更​​新組件的狀態。當州更新這個功能完成它的工作。 –