2017-04-09 101 views
6

我知道我不應該直接做出反應突變狀態,但怎麼樣的情況,當我使用功能:我可以改變傳遞給setState函數的狀態嗎?

onSocialClick = e => { 
    const id = e.target.value; 
    this.setState((prevState, props) => { 
     prevState[id] = !(prevState[id]); 
     return prevState; 
    }); 
}; 

它是一個錯誤的修改傳遞的對象?

編輯:

事實證明,我們大多數人都錯在這裏。 React docs state it clearly現在:

prevState是對之前狀態的參考。它不應該直接變異。相反,應該通過建立一個基於prevState和道具輸入的新對象來表示更改。

感謝@TomášHübelbauer在評論中指出。

+3

這是不是一個錯誤:)不直接修改狀態意味着你應該使用'setState',而不是'this.state = ...'。如果你這樣做 - 一切都好,無論你用什麼傳入參數。 – elmeister

+0

@Tomasz我問了一個後續問題,因爲我懷疑你的代碼片段。您可能會覺得這很有趣:https://stackoverflow.com/q/47339643/2715716 –

+1

@TomášHübelbauer謝謝!我做了一個編輯。 – Tomasz

回答

-1

直接改變狀態是非常不鼓勵的。此外,你正在改變以前的狀態,然後返回它沒有多大意義。如果你想要的是在state[id]切換狀態,然後修復你的代碼更喜歡:

onSocialClick = e => { 
    const id = e.target.value; 
    this.setState({this.state[id]: !this.state[id}); 
}; 
+0

這是不鼓勵的,你應該使用OP所使用的功能方式(但也許直接使用感興趣的道具 –

3

一個清潔的方法是直接引用你想要做的屬性編輯:

doIt =() => this.setState(({ [id]: prevValue }) => ({ 
    [id]: !prevValue, 
})); 
+0

如果'[id]'不是'state'的直接子節點,可以這樣做,但是一個級別在我的情況下,我有一個'[ID]'陣列,所有其他Q/A和文章建議複製,但我覺得你的解決方案更清楚。 –

+0

@ Al.G。你可能會使用'find'獲取正確的索引來訪問正確的數組元素 –

1

你做這件事的方式沒有錯。它完全okk修改參數,然後返回它。然而,隨着prevState參數的setState用於當你修改基礎上,prevState的值的狀態下,它prefectly適合您的方案和更清潔的處理方式,將

onSocialClick = e => { 
    const id = e.target.value; 
    this.setState((prevState, props) => { 
     return {[id] : !(prevState[id])}; 
    }); 
}; 
相關問題