簡體   English   中英

如何正確更新反應狀態

[英]How to update react state properly

我是新來的反應者,我想問問更新狀態的最佳方法是什么,我有一些代碼。 我知道以下代碼不正確,因為它直接設置了狀態。

handlexxx = foo => { 
  const foos = [...this.state.foos]; 
  const index = foos.indexOf(foo); 
  foos[index].bar = !foo.bar; 
  this.setState({ foos }); 
};

這兩個代碼下面哪個更好? 有人可以幫我解釋一下!

handlexxx = foo => { 
  const foos = [...this.state.foos]; 
  const index = foos.indexOf(foo); 
  foos[index] = { ...foo }; 
  foos[index].bar = !foo.bar; 
  this.setState({ foos }); 
};

handlexxx = foo => { 
  const foos = [...this.state.foos];
  const index = foos.indexOf(foo); 
  foos[index] = { ...foos[index] };
  foos[index].bar = !foos[index].bar;
  this.setState({ foos }); 
};

我的帳戶被一些否決問題所困擾,有趣的是,即使我已經接受了答案,我也必須重新編輯它們。我不知道這樣做的意義。這個Stackoverflow系統讓我很沮喪。

現在,除了繼續編輯我的問題外,我基本上無能為力,並且所有問題都已得到解答。 這是荒唐的 !!!

您應該使用Array.prototype.map()方法,如下所示:

handlexxx = foo => { 
  const foos = this.state.foos.map(f => {
    if(foo.id === f.id) return {...f, bar: !f.bar};   // assume that the element has an identifier id
    return f;
  })
  this.setState({ foos }); 
};

簡而言之,使用ternary operator代替if-else語句

handlexxx = foo => { 
  const foos = this.state.foos.map(f => foo.id === f.id ? {...f, bar: !f.bar} : f
  this.setState({ foos }); 
};

即使對於復雜的嵌套對象,也可以避免變異的一種經典方法是使用JSON.parse(JSON.stringify(COMPLICATED_OBJECT)) 這將返回沒有引用原始對象的對象表示形式,因此您可以在不影響原始對象的情況下對副本進行突變:

var foos = [
  { id: 1, bar: false },
  { id: 2, bar: false },
  { id: 3, bar: false },
]

var foo = foos[0];

var _foos = JSON.parse(JSON.stringify(foos)).map(f => {
  if (f.id === foo.id) f.bar = !foo.bar;
  return f;
});

如果運行此命令,則會看到foos不變,但_foos已更新

歸根結底,您可能需要考慮最容易閱讀的解決方案,以及團隊中其他開發人員最容易閱讀的解決方案。 如果您必須在3年后再次使用此代碼,則希望能夠從頁面上讀取代碼而不會刮花頭。

由於您的foo對象具有id屬性,因此最好使用.map方法,並將其與擴展語法或Object.assign混合使用,然后按照@NguyễnThanhTú的說明返回相關元素。 但是,如果要使用索引執行此操作,請參見以下示例。

您可以使用findIndex ,而不是indexOf 由於indexOf只是尋找一個值,因此findIndex接受一個函數。 查找項目的索引,映射數組,然后如果索引匹配,則執行更改(如果不匹配),則返回不相關的項目。

 state = { foos: [ { id: 1, bar: true }, { id: 2, bar: false }, { id: 3, bar: false }, ], }; const foo = { id: 2, bar: false }; const handleState = foo => { const index = state.foos.findIndex(el => el.id === foo.id ); const newFoos = state.foos.map( ( foo, i ) => { if ( i !== index ) { return foo }; return { ...foo, bar: !foo.bar }; }) console.log( newFoos ); } handleState(foo); 

第二個。 在這里,我們以一種棘手的方式使用Object.assign 代替映射數組,我們使用Object.assign並使用其索引更改項目。

 state = { foos: [ { id: 1, bar: true }, { id: 2, bar: false }, { id: 3, bar: false }, ], }; const foo = { id: 2, bar: false }; const handleState2 = foo => { const index = state.foos.findIndex(el => el.id === foo.id ); const newFoos = Object.assign( [], state.foos, { [index]: { ...foo, bar: !foo.bar } }); console.log( newFoos ); } handleState2(foo); 

第三個。 沒有索引,只有.map並直接使用id屬性。 我們不需要在這里找到索引,我們只需要檢查id屬性以找到正確的項目。

 state = { foos: [ { id: 1, bar: true }, { id: 2, bar: false }, { id: 3, bar: false }, ], }; const foo = { id: 2, bar: false }; const handleState3 = foo => { const newFoos = state.foos.map( el => { if ( el.id !== foo.id ) { return el }; return { ...el, bar: !el.bar }; }) console.log( newFoos ); } handleState3( foo ); 

暫無
暫無

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

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