【问题标题】:Why is this react component rendering twice?为什么这个反应组件渲染两次?
【发布时间】:2018-05-02 09:46:07
【问题描述】:

问题是组件被渲染了两次,一次是初始状态,一次是在 axios promise 中的 setState 方法之后。为什么会发生这种情况,我该如何解决。

我同时使用了 componentWillMount 和 componentDidMount。我作为菜鸟,努力尝试,但未能弄清楚原因。

export default class Dashboard extends Component{

  constructor(props) {
    super(props)
    this.state = {
      data: {
        okay: 'lul'
      }
    }
  }

  componentWillMount() {
    axios
      .get('/api/data?param1='+this.props.location.state.param1+'&param2='+this.props.location.state.param2)
      .then(res => {
        if (res.status != 401) {
          if(res.err)
            console.log('Error while retrieving: ', res.err)
          else {
            this.setState({
              data: res.data.data
            })
          }
        } else {
          console.log('Unauthorized!');
        }
      })
  }

  render() {
    return (
        <Segment inverted vertical>
          <CardContainer data={this.state.data}/>
        </Segment>
    )
  }
}

即使是与 React / JS / 通用编程相关的基本建议也非常感谢

【问题讨论】:

  • 你为什么认为这是个问题?如果您不想在获取数据之前显示任何内容,您可以在 render 方法中检查this.state.data,如果还没有数据可以显示,则返回nullsetState 将导致每次调用render 方法。
  • @HåkenLid 您提出的解决方案非常有效。但是我怎样才能用正确的数据只渲染一次组件呢?我是不是必须在构造函数里面写 axios 请求,然后设置初始状态?
  • 这种行为是 react 应该如何工作的。这不是一个错误。调用 render 真的很便宜,因为 react 会以有效的方式更新 dom。在某些情况下,您可能希望在重新渲染发生时进行调整。这在此处的反应文档中进行了讨论:shouldComponentUpdate In Action

标签: reactjs


【解决方案1】:

您在 componentWillMount 中有一个异步请求,因此在请求完成之前,您的组件会被渲染,但是一旦异步请求成功,您就会有一个触发重新渲染的 setState 函数调用,因此您的组件会被渲染两次

这是预期的行为。

您可以查看此问题了解更多详情

Use componentWillMount or componentDidMount lifecycle functions for async request in React

根据文档

componentWillMount() 在安装发生之前被调用。它在 render() 之前调用,因此在该方法中调用 setState() synchronously 不会触发额外的渲染。

这意味着如果你写

componentWillMount() {
   this.setState({count: 1});
}

状态将反映在初始渲染本身并触发不渲染。但是,如果您有一个异步方法,那么如果异步请求在已经调用渲染之后完成,则在其中调用 setState 可能会触发额外的渲染。

为了更加强调这一事实,您不能再使用componentWillMount,因为React 正在逐步从未来的主要版本中删除此方法。而是使用 componentDidMount。

【讨论】:

  • 我知道了。因此,无论何时设置状态,都会调用 render 方法。但是他们说反应是“智能的”,不会进行冗余渲染。你说什么?
  • React 不会在 dom 中做冗余渲染,但它仍然会调用 render 方法,就是在这里做一个虚拟 DOM diffing 决定是否渲染。
  • 上面写着“在这个方法中调用 setState() 会触发一个额外的渲染,但它保证在同一个 tick 中刷新。这保证了即使 render() 将被调用两次在这种情况下,用户将看不到中间状态”。我只有两个状态实例,initial 和 setState。中间状态是初始状态吗?
  • 在 componentWillMount 中同步调用 setState 不会触发额外的渲染,但由于这里有额外的 async 方法,它会触发额外的重新渲染
猜你喜欢
  • 2020-10-11
  • 2020-03-17
  • 2021-10-21
  • 2017-11-22
  • 2020-08-17
  • 2020-07-11
  • 2017-06-23
  • 2020-03-17
  • 2020-10-01
相关资源
最近更新 更多