【问题标题】:setState in React based on current state根据当前状态在 React 中设置状态
【发布时间】:2017-07-18 14:40:31
【问题描述】:

在 React 中更新有状态组件时,如果组件使用当前状态来更新新状态,这被认为是一种不好的做法。

例如,如果我有一个类来存储过滤器是否处于打开状态,那么这些用于更新状态的选项之一在性能方面是否比另一个更可取?

选项 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}
        />
    }
}

【问题讨论】:

  • 我不明白为什么这会被认为是不好的做法,除了状态更改是异步和可合并的。这可能是一个合理的担忧——你可能得不到你所期望的。我个人更喜欢选项#3。
  • 这确实是一种不好的做法,出于您提到的原因,存在合理的担忧,并且还概述了in the docs

标签: javascript reactjs setstate


【解决方案1】:

组件访问自己的状态并没有错。只写状态不会非常有用!但是,在将组件状态或状态更改方法暴露给其他组件时,您应该非常小心。组件状态是内部的,只能通过经过深思熟虑的界面从外部触摸,以防止您的组件变得一团糟。

其实有一个例子和你的 Example #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')
);

但是,请注意与您的示例不同。 toggle 方法需要在构造函数中绑定,以确保 this 表示您所期望的含义。

如果包装组件是跟踪子组件ExternalComponent 可见性的组件,那么与其将切换方法传递给子组件,我希望包装器呈现某种隐藏/显示功能,然后要么将当前可见性作为道具传递给子组件,要么选择性地渲染它(请注意,选择性渲染将导致整个子组件在再次启用时重新安装,这可能很昂贵;你最好隐藏它而不是将其拆除并重新创建)。这使得关注点的划分变得清晰:包装器知道可见性,子组件不需要知道如何或为什么做出该决定,也不需要接触包装器的内部状态。

【讨论】:

    【解决方案2】:

    使用当前状态的值来确定新的状态值并没有错。

    选项 2 的代码更少,这对我很有吸引力。但是,有时在使用第三方组件(例如 Semantic UI React 模态)时我可能不得不使用选项 1,并且它具有我们必须定义的显示和隐藏处理程序。

    选项 3 也可以;我会将它用于除此显示/隐藏应用程序之外的其他应用程序(事实上,几乎一直使用该应用程序,尤其是当您控制输入组件时)。

    【讨论】:

      猜你喜欢
      • 2021-03-28
      • 1970-01-01
      • 1970-01-01
      • 2021-10-31
      • 2019-10-20
      • 2013-01-07
      • 2016-10-27
      • 1970-01-01
      • 2017-06-11
      相关资源
      最近更新 更多