2017-02-27 68 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也很好;我将其用于其他应用程序,而不是显示/隐藏其他应用程序(实际上,这个应用程序几乎总是使用,尤其是当您控制输入组件时)。