簡體   English   中英

反應componentdidupdate引發無限循環

[英]react componentdidupdate provokes infinite loop

我使用onChange觸發對elasticsearch的API調用,以便我可以提示自動完成列表。 為了確保我的商店在重新渲染之前得到更新,我添加了componentDidMount,這樣我就不會落后了。 但要達到這一點需要代碼,所以:

constructor(props) {
  super(props)
  this.state = {
    inputValue: '',
    options: []
  };
  this.props = {
    inputValue: '',
    options: []
  };
  this._onChange = this._onChange.bind(this);
}

componentDidMount() {
  CodeStore.addChangeListener(this._onChange);
}

_onChange(event) {
  if (this.state.inputValue && !event) {
    var enteredChars = this.state.inputValue;
    console.log('NO EVENT!');
  } else if (event.target.value) {
    console.log('EVENT!');
    var enteredChars = event.target.value;
    this.setState({inputValue: enteredChars});
  }
  CodeService.nextCode(enteredChars);
}

正如您所看到的,我添加了一些日志事件,以確保我的狀況正常。 我讀到有關setState引發一個rerender所以它在條件內,但沒有停止循環。 控制台日志確認狀態切換。 但是在我的條件中使用setState會使功能setState並且我沒有得到列表。

這是我的日志:

                        0
Home.jsx:48             EVENT!
Home.jsx:50             0
CodeService.js:27       request
CodeActions.js:10       dispatch
CodeStore.js:22         store
Home.jsx:43             1
Home.jsx:46             NO EVENT!
10OptionTemplate.jsx:15 render-list
CodeService.js:27       request
CodeActions.js:10       dispatch
CodeStore.js:22         store
Home.jsx:43             1
Home.jsx:46             NO EVENT!
10OptionTemplate.jsx:15 render-list
CodeService.js:27       request
CodeActions.js:10       dispatch
CodeStore.js:22         store
Home.jsx:43             1
Home.jsx:46             NO EVENT!

無論如何,無限循環不會影響性能。 我認為由於componentWillUnmount但必須避免大量的API調用。 希望這是任何證據的足夠信息。

看起來無限循環是由以下模式引起的:

  1. 用戶類型輸入
  2. _onChange更新state + fires要存儲的操作
  3. 存儲更新並發送更改事件
  4. 存儲更改事件觸發相同的 _onChange事件
  5. _onChange不會更新狀態,但會觸發存儲操作
  6. 轉到第3步並重復(無限期)

要修復的步驟:

  • 為用戶輸入和商店更新制作不同的更改處理程序(正如@Janaka Stevens所建議的那樣)
  • 將商店中的數據放入狀態
  • 用戶輸入不必處於狀態(如果您的反應代碼沒有為輸入字段提供值,它將以空值開頭,並保留單獨輸入的內容)

然后你的代碼看起來像這樣:

constructor(props) {
  super(props)
  this.state = {
    options: []
  };
  // removed the this.props bit: props should not be updated inside component
  this._onChangeUser = this._onChangeUser.bind(this);
  this._onChangeStore = this._onChangeStore.bind(this);
}

componentDidMount() {
  CodeStore.addChangeListener(this._onChange);    // this is OK
}

_onChangeUser(event) {
  console.log('EVENT!');
  var enteredChars = event.target.value;
  CodeService.nextCode(enteredChars);
  // No need to update state here - go to sleep until store changes
}

_onChangeStore() {
  var newList = getListFromStore();  // your own function to get list from store
  this.setState({ options: newList});            // update state here
}

不確定你的意思是'一個嘀嗒嘀嗒',或者是什么導致它,但是清理無限循環是一個好的起點;)

PS:上面的代碼只是草圖,可能有拼寫錯誤。

看起來您正在為輸入事件和存儲偵聽器使用_onChange。 他們需要單獨的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM