为什么我的React组件渲染两次?

时间:2018-02-17 21:51:40

标签: javascript reactjs firebase google-cloud-firestore

我不知道为什么我的React组件渲染两次。所以我从params中提取一个电话号码并将其保存到状态,以便我可以搜索Firestore。一切似乎工作得很好,除了它呈现两次......第一个呈现电话号码和零点。第二次渲染所有数据都正确显示。有人可以指导我解决方案。

from sqlalchemy import Model, Column, Integer

class MyModel(Model):
    id = Column(Integer, primary_key=True)

4 个答案:

答案 0 :(得分:7)

React在getPoints完成异步操作之前渲染组件。

因此,第一个render显示points的初始状态0,然后调用componentDidMount并触发异步操作。
完成异步操作并更新状态后,将使用新数据触发另一个render

如果需要,您可以显示正在获取数据的加载程序或指示符,但尚未准备好显示conditional rendering

只需添加另一个布尔键,如isFetching,在调用服务器时将其设置为true,并在收到数据时将其设置为false。

您的渲染可能如下所示:

render() {
  const {isFetching} = this.state;
  return (
    <div>
    {
        isFetching ? <div>Loading...</div> : (
      <div>
        <p>{this.state.phoneNumber} has {this.state.points} points...</p>
            <p>Would you like to redeem or add points?</p>
        </div>
        <div>
                <button>Redeem Points</button>
                <button>Add Points</button>
            </div>
        </div>  
      )
    }
  );
}

答案 1 :(得分:1)

这是因为 React 严格模式代码。

Remove -> React.StrictMode,来自 ReactDOM.render 代码。

将在每次重新渲染时渲染 2 次:

ReactDOM.render(
  <React.StrictMode>
<App />
  </React.StrictMode>,
  document.getElementById('root')
);

将渲染 1 次:

ReactDOM.render(
  <>
<App />
  </>,
  document.getElementById('root')
);

PS 没有冒犯那些说不要担心“它重新渲染多少次”的人......如果你通过 setTimeout 每 1 秒运行一个永久的 API 获取代码,并且每次使用 API 都会花费它你 0.01 美分,每次重新渲染它都会触发 setTimeout 函数 2 次(这意味着你每秒调用次数增加一倍),这意味着在 5 秒后你运行 1000+ setTimeouts 每个调用 API 同时和之后1 小时,这个数字将变成一万亿+,所以如果你弄错了,成本将变得天文数字。此问题已通过移除 React.StrictMode 修复,因此代码将 WAI。

答案 2 :(得分:0)

React使用其虚拟dom及其差异算法在内部监视和管理其渲染周期,因此您不必担心重新渲染的次数。让重新渲染以做出反应。即使render函数被调用,如果其中没有props或状态更改,则仍有一些子组件不会在ui上刷新。每个setstate函数调用都会通知react检查diffing算法并调用render函数。

因此,在您的情况下,由于在getPoints函数中定义了setstate,因此它会告诉反应通过渲染函数重新运行差异过程。

答案 3 :(得分:0)

您正在以严格模式运行应用程序。转到index.js并注释严格模式标记。您将找到一个渲染器。

这是React.StrictMode的故意功能。它仅在开发模式下发生,应有助于在渲染阶段发现意外的副作用。