【问题标题】:Where should I update state?我应该在哪里更新状态?
【发布时间】:2017-02-13 01:18:10
【问题描述】:

我有一个组件,我在 componentDidMount 函数中更新了状态。我收到一条 linter 警告,将我指向此页面:

https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-did-mount-set-state.md

它说

防止在componentDidMount(no-did-mount-set-state)中使用setState

在组件挂载后更新状态将触发第二次 render() 调用,并可能导致属性/布局抖动。

我应该在哪里更新我的状态?

这是我的 componentDidMount 函数:

  componentDidMount(){
    this.interval = setInterval(() => {
      this.setState({
        frame: this.state.frame + 1
      });
    }, this.props.interval);
  }

这是我的渲染函数:

render(){
    let dots = this.state.frame % (this.props.dots + 1);
    let text = '';
    while(dots > 0){
      text += '.';
      dots--;
    }
    return <span {...this.props}>{text}&nbsp;</span>;
  }

我的构造函数:

   constructor(props, context){
    super(props, context);

    this.state = {frame: 1}; 
}

【问题讨论】:

  • 构造函数呢?

标签: reactjs


【解决方案1】:

实际上,你没有使用setState,你定义的异步操作将使用setState,我相信这条规则是关于同步操作setState,所以如果你确定第一次渲染将是在触发间隔之前,您可以在 eslint 配置中禁用此规则。

查看来自 @ljharb https://github.com/airbnb/javascript/issues/684#issuecomment-264094930

的此线程和 cmets

在 componentDidMount 中执行 setState 将导致可见的渲染闪烁。

但是,在进行服务器渲染时,任何需要浏览器环境的东西都必须放在 componentDidMount 中,因为它只在客户端运行,但 componentWillMount 在客户端和服务器上都运行。

【讨论】:

  • 我明白你对异步操作的意思。即使我在 linter 中禁用了警告,我也会在浏览器控制台中收到以下信息:警告:setState(...):只能更新已安装或正在安装的组件。这通常意味着您在未安装的组件上调用了 setState()。这是无操作的。
  • 你要删除componentWillUnmount() 的计时器吗?否则,我看不出您会如何收到该警告。
  • 啊.. 我拼错了 componentWillUnmount.. :(。将此标记为正确,因为忽略该错误似乎是合法的,而另一个警告是因为我的不相关的错误。谢谢大家
猜你喜欢
  • 2015-10-22
  • 2011-07-31
  • 1970-01-01
  • 2019-06-07
  • 2020-03-20
  • 1970-01-01
  • 2019-08-10
  • 1970-01-01
  • 2013-01-22
相关资源
最近更新 更多