1

我正在製作一個非常簡單的React組件,它顯示從遠程源獲取的數據。獲取數據之前,它必須等待用戶在正確登錄這裏是我正在試圖做到這一點:如何從`componentDidUpdate`內部調用`dispatch`而不會以無限循環結束?

class MyComponent extends React.Component { 
    componentDidUpdate() { 
    if (this.props.loggedIn) { 
     api.getData() 
     .then(() => { 
      this.props.dispatch({ 
      type: 'gotData' 
      }) 
     }, (reason) => { 
      this.props.dispatch({ 
      type: 'getDataFailed' 
      }) 
     }) 
    } 
    } 
} 

在我自己的話,每一次相關與這個國家的一部分組件(在這種情況下,loggedIn道具)進行更新,componentDidUpdate叫,我可以得到的數據,如果我看到在用戶登錄

這實際上工作得非常好,但有一個主要問題:似乎呼籲dispatch最終再次觸發componentDidUpdate,所以我最終在一個無限循環。我甚至不必在任何地方監聽這些調度事件,使用dispatch函數的簡單事實足以再次觸發componentDidUpdate

我的猜測是調度執行我的根減速器,它在內部使用setState,從而再次觸發整個生命週期鏈。

這種事情通常是怎麼完成的?如何在componentDidUpdate之內撥打dispatch而不結束無限循環?

+0

我會考慮使用帶有componentWillReceieveProps()的子組件。將狀態作爲道具傳遞給該組件 –

回答

0

解決此問題的一個簡單方法是添加一個額外的標誌,例如loggingIn,您在異步操作之前設置(通過分派)並在之後重置。您還需要跟蹤,當登錄失敗,以區別於當登錄過程尚未啓動這一情況(除非你想自動重新啓動該進程失敗上)的:

class MyComponent extends React.Component { 
    componentDidUpdate() { 
    const { loggedIn, loggingIn, loginFailed, dispatch } = this.props; 
    if (!loggingIn && !loggedIn && ! loginFailed) { 
     dispatch({ 
     type: 'gettingData' // this one sets loggingIn to true, loggedIn to false, loginFailed to false 
     }); 
     api.getData() 
     .then(() => { 
      dispatch({ 
      type: 'gotData' // this one sets loggingIn to false, loggedIn to true, loginFailed to false 
      }) 
     }, (reason) => { 
      dispatch({ 
      type: 'getDataFailed' // this one sets loggingIn to false, loggedIn to false, loginFailed to true 
      }) 
     }) 
    } 
    } 
} 

如果你不希望設置這種狀態在終極版,你也可以有這樣的控制您的組件本身存在:

class MyComponent extends React.Component { 
    componentDidUpdate() { 
    const { loggedIn, dispatch } = this.props; 
    const { loggingIn, loginFailed } = this.state; 

    if (!loggingIn && !loggedIn && !loginFailed) { 
     this.setState({ 
     loggingIn: true 
     }) 
     api.getData() 
     .then(() => { 
      this.setState({ 
      loggingIn: false, 
      loginFailed: false 
      }); 
      dispatch({ 
      type: 'gotData' 
      }) 
     }, (reason) => { 
      this.setState({ 
      loggingIn: false, 
      loginFailed: true 
      }); 
      dispatch({ 
      type: 'getDataFailed' 
      }) 
     }) 
    } 
    } 
} 

您可以使用loggingIn標誌來顯示一個微調您的用戶,或loginFailed標誌來顯示一個消息,如果適合你的UX。

0

當您收到登錄狀態時,將您的api呼叫轉移到操作中!事情是這樣的:

api.getUserLoggedInStatus().then((status) => { 
 
    dispatch({ 
 
    type: 'loggedInStatus', 
 
    status 
 
    }); 
 
    api.getData.... // and dispatch 
 
};

這種流動將避免任何循環或競爭條件。