基于当前状态在 React 中设置状态 [英] setState in React based on current state

查看:58
本文介绍了基于当前状态在 React 中设置状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When updating a stateful component in React is it considered a bad practice when a component uses the current state to update the new state.

例如,如果我有一个类来存储过滤器在其状态下是否打开,那么就性能而言,这些更新状态的选项之一是否比另一个更可取?

For example if I have a class that stores whether a filter is open or not in it's state, is one of these options for updating the state more desirable than the other in terms of performance?

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

推荐答案

组件访问自己的状态没有任何问题.只写状态不会非常有用!但是,在向其他组件公开组件状态或状态更改方法时应该非常小心.组件状态是内部的,只能通过精心设计的接口从外部接触,以防止您的组件变得一团糟.

There is nothing wrong with a component accessing its own state. Write-only state wouldn't be terribly useful! However, you should be very careful when exposing component state or state-altering methods to other components. Component state is internal, and should only been touched from outside via a well-considered interface, to prevent your components from becoming an entangled mess.

事实上,有一个例子类似于你的例子#2 在React 文档:

In fact, there is an example that is similar to your 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')
);

但是,请注意与您的示例的不同之处.需要在构造函数中绑定切换方法,以确保 this 表示您期望的意思.

Note a difference from your example, however. The toggle method needs to be bound in the constructor, to ensure that this means what you're expecting it to mean.

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

If the wrapping component is the one keeping track of the visibility of the child ExternalComponent, then rather than passing the toggle method into the child component, I would expect the wrapper to render a hide/show affordance of some sort, and then either pass the current visibility into the child component as a prop or selectively render it (note that selective rendering will cause the entire child component to be remounted when it's enabled again, which may be expensive; you may be better off hiding it than tearing it down and recreating it). That makes the division of concerns clear: the wrapper knows about visibility, and the child component doesn't need to know how or why that decision was made, nor does it need to touch the wrapper's internal state.

这篇关于基于当前状态在 React 中设置状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆