2017-02-27 63 views
2

當更新狀態的組件在陣營是它被認爲是不好的做法,當一個組件使用當前狀態更新新的狀態。的setState反應根據當前狀態

例如,如果我有一個存儲過濾器是否打開或沒有在它的國家一類,是這些選項在性能方面的更新狀態比其他更可取呢?

選項1:

class Container extends Component { 
    state = { 
     show: false 
    } 

    show =() => this.setState({ show: true }) 

    hide =() => this.setState({ show: false }) 

    render() { 
     <ExternalComponent 
      show={this.show} 
      hide={this.hide} 
     /> 
    } 
} 

選項2:

class Container extends Component { 
    state = { 
     show: false 
    } 

    toggleVisibility =() => this.setState({ show: !this.state.show }) 

    render() { 
     <ExternalComponent 
      toggleVisibility={this.toggleVisibility} 
     /> 
    } 
} 

方案3:

class Container extends Component { 
    state = { 
     show: false 
    } 

    setShow = (newVal) => this.setState({ show: newVal }) 

    render() { 
     <ExternalComponent 
      setShow={this.setShow} 
     /> 
    } 
} 
+4

我不明白爲什麼這會被認爲是不好的做法,除了狀態更改是異步和可合併的。這可能是一個合理的擔憂 - 你可能得不到你的期望。我個人更喜歡選項#3。 –

回答

3

沒有什麼錯與組件訪問自己的狀態。只寫狀態不會非常有用!但是,在將組件狀態或狀態更改方法暴露給其他組件時,您應該非常小心。組件狀態是內部的,只能通過一個經過深思熟慮的界面從外部觸及,以防止組件陷入糾結混亂。

事實上,存在類似於你的實施例#2 in the React documentation一個例子:

class Toggle extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = {isToggleOn: true}; 

    // This binding is necessary to make `this` work in the callback 
    this.handleClick = this.handleClick.bind(this); 
    } 

    handleClick() { 
    this.setState(prevState => ({ 
     isToggleOn: !prevState.isToggleOn 
    })); 
    } 

    render() { 
    return (
     <button onClick={this.handleClick}> 
     {this.state.isToggleOn ? 'ON' : 'OFF'} 
     </button> 
    ); 
    } 
} 

ReactDOM.render(
    <Toggle />, 
    document.getElementById('root') 
); 

注意從示例的差異,但是。切換方法需要在構造函數中綁定,以確保this意味着您期望它的意思。

如果包裝組件是跟蹤子女ExternalComponent的可見性的那個,那麼我不會將切換方法傳遞給子組件,而是期望包裝器呈現某種類型的隱藏/顯示可供件,並且然後將當前的可見性作爲道具傳遞給子組件或選擇性地渲染它(請注意,選擇性渲染將導致整個子組件在再次啓用時重新安裝,這可能很昂貴;您可能最好隱藏它而不是撕裂它下來並重新創建它)。這使得關注點分清楚:包裝器知道可見性,而子組件不需要知道如何或爲什麼做出該決定,也不需要觸摸包裝器的內部狀態。

1

沒有什麼錯誤使用當前狀態的值,以確定新的狀態值。

選項2具有更少的代碼,哪一種吸引我的。但是,有時我可能不得不在使用第三方組件時使用選項1(例如Semantic UI React模式),並且它顯示並隱藏了我們必須定義的處理程序。

選項3也很好;我將其用於其他應用程序,而不是顯示/隱藏其他應用程序(實際上,這個應用程序幾乎總是使用,尤其是當您控制輸入組件時)。