javascript - 为什么我的状态声明后我的 React 渲染两次?
问题描述
我的 React 项目似乎将所有内容渲染了两次(我在调用 console.log 并获得 2x 之后注意到)当我第一次在我的应用程序中声明状态时,它似乎正在发生,在状态渲染之前的日志在 2x 之后呈现日志。
此外,声明状态后的 componentDidMount 仅呈现一次
import React, { Component } from "react";
import { getProteins } from "./services/proteinsService";
import ProteinBuilder from "./containers/ProteinToolbar/ProteinBuilder.jsx";
import BlendOutput from "./containers/BlendOutput/BlendOutput";
import "./App.css";
console.log("App before state");
class App extends Component {
state = { proteins: getProteins() };
componentDidMount() {
console.log("componentDidMount");
}
render() {
console.log("App after state");
return (
<div className="container">
<div className="row">Nav</div>
<div className="row">
<div className="col col-sm-3">
<ProteinBuilder proteins={this.state.proteins} />
</div>
<div className="col-sm-9">
<div className="row">
<div className="col-12 BlendOutput border rounded">
<BlendOutput proteins={this.state.proteins} />
</div>
</div>
</div>
</div>
</div>
);
}
}
export default App;
我的 getProteins() 来自以下内容:
const proteins = [
{
_id: 1,
name: "Pea Protein Isolate",
description: "Pea Protein Isolate",
digestibility: 0.98,
AA: {
His: 2.5,
Ile: 4.5,
Leu: 8.4,
Lys: 7.2,
MetCys: 2.1,
PheTyr: 9.3,
Thr: 3.9,
Trp: 1,
Val: 5
},
percentOfBlend: 0.382
},
{
_id: 2,
name: "Texturized Pea Protein",
description: "Texturized Pea Protein",
digestibility: 0.94,
AA: {
His: 2.0,
Ile: 3.91,
Leu: 6.84,
Lys: 5.96,
MetCys: 2.69,
PheTyr: 7.31,
Thr: 3.02,
Trp: 0.84,
Val: 4.23
},
percentOfBlend: 0.448
},
{
_id: 3,
name: "Sacha Inchi Protein",
description: "Sacha Inchi",
digestibility: 0.92,
AA: {
His: 2.6,
Ile: 5,
Leu: 6.4,
Lys: 4.3,
MetCys: 3.7,
PheTyr: 7.9,
Thr: 4.3,
Trp: 2.9,
Val: 4
},
percentOfBlend: 0.17
},
{
_id: 4,
name: "Potato Protein",
description: "Potato protein isolate",
digestibility: 0.95,
AA: {
His: 1.7,
Ile: 5.6,
Leu: 9.2,
Lys: 7.1,
MetCys: 3.2,
PheTyr: 11.6,
Thr: 4.4,
Trp: 1.4,
Val: 8
},
percentOfBlend: 0.0
}
];
export function getProteins() {
return proteins;
}
export function multiplyProteins() {
proteins.map(proteins.AA.map());
}
解决方案
setState
我在下面的代码段中创建了您案例的简化版本,如果从未调用过,则看不到相同的行为。因此,我认为问题在于:
- 子组件正在调用 setState,并导致重新渲染
- 父组件导致重新渲染
- 您启用了StrictMode 。
这个片段对渲染生命周期中发生的事情进行了细分。注释掉设置状态的部分,你有一个应该和你发布的一样的例子,减去子组件。
console.log("create App component");
function setFoo(){console.log('setting foo'); return 'bar'}
class App extends React.Component {
state = { foo: setFoo() };
componentDidMount() {
console.log("componentDidMount. Current state", this.state);
this.setState(
{qux: 'quo'},
() => console.log('setState callback (set state has been fully applied) has state', this.state)
)
console.log("componentDidMount -> this.setState() was called (but may not have been applied). Current state", this.state)
}
render() {
console.log("App.render() with state", this.state);
return (
<div>
{JSON.stringify(this.state)}
</div>
);
}
}
console.log('before dom render')
ReactDOM.render(<App/>, document.getElementById('app'))
console.log('after dom render')
<div id="app" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
如果您想尝试使用该代码段,您可能还想尝试setState
连续多次调用,并查看每次调用后状态会发生什么。
推荐阅读
- java - JavaFX:加载 FXML 后如何添加到 GUI
- c# - NET Core 3 服务 - 服务管理器不会等待服务启动
- testng - TestNg 报告仅在最后生成
xml上的标签 - java - 如何使用 javax.json lib 迭代更多 JsonObject
- java - 使用 jsoup 或任何其他库通过原始 xpath 从 HTML 中删除元素
- java - 在java jtextfield中按3组用空格分割数字
- c++ - 构造和销毁对象
- javascript - 多个滑块在代码中重复我自己
- c++ - MySQL命令阶段没有来自服务器的响应
- python - Python 错误 FileNotFoundError: [Errno 2] 没有这样的文件或目录