reactjs - React - 多个组件确实更新了 - 为什么?
问题描述
作为 React 的新手,我正在尝试了解生命周期钩子,这种情况是 ComponentDidUpdate()
所以我有一个位置类组件——它是一个简单的表单,用户可以输入一个位置。我的 handleSubmit 事件阻止了新的页面请求,而是更新了这个高阶组件中的状态。
在位置内,我有一个天气类组件,它接收新位置作为道具,用位置更新自己的状态,并在 componentDidUpdate() 上触发 api 请求,然后一旦获取解决,它还会使用该位置的天气条件设置其状态. 然后它将状态传递给 jsx div,以便用户可以查看天气状况。
为此,我可以看到从天气组件输出到控制台的三个 componentDidUpdate() 事件——我只是在猜测导致它们的原因。
第一次从更高的位置组件接收到新的位置道具?
第二个将它自己的状态设置为新位置?
第三个当提取被解决并设置天气状态?
或者可能是当它根据天气状况更新 div 时。
请你能告诉我发生了什么,它真的会帮助我构建一个更好的应用程序并调试它。
谢谢,
菲尔
本地组件:
import React, { Component } from "react";
import './local.css';
import Earth from './Earth';
import { Weather } from '../spies/weather/Spy';
class Local extends Component {
constructor() {
super()
this.state = {
location:''
}
}
handleSubmit = e => {
e.preventDefault();
if(e.target.elements.localInput.value) this.setState({ location: e.target.elements.localInput.value })
else return;
}
render() {
return (
<React.Fragment>
<div id="local" >
<form className="appBorder" onSubmit={this.handleSubmit}>
<input id="localInput" className="appInput appBorder" type="text" placeholder="Enter the location">
</input>
<button className="appButton">
<Earth className="earth"/>
</button>
</form>
</div>
<Weather location={this.state.location}/>
</React.Fragment>
)
}
}
export default Local;
Weather 组件(别名 Spy):
import React, { Component } from "react";
import './weather.css';
import '../spy.css';
import { getWeather } from './api';
class Spy extends Component {
constructor() {
super()
this.state = {
location: null,
weatherData: null,
error: '',
};
}
componentDidUpdate(prevProps, prevState) {
console.log("update");
if (prevProps.location !== this.props.location) {
this.setState({location: this.props.location},()=>{
getWeather(this.state.location)
.then(data => {
console.log("api request resolved");
this.setState({ weatherData: data });
})
.catch(error =>
this.setState({ error: error.message }));
}
)}
else return;
}
render() {
return (
<div id="spyWeather" className="appBorder spy">
<h3 className="spyName">Weather for {this.state.location}</h3>
<p id="weatherDesc" className="spyData">Conditions: {this.state.weatherData ? this.state.weatherData.current.weather_descriptions : ""}</p>
<p id="weatherTemp" className="spyData">Temperature: {this.state.weatherData ? this.state.weatherData.current.temperature : ""} °C</p>
<p id="weatherHumid" className="spyData">Humidity: {this.state.weatherData ? this.state.weatherData.current.humidity : ""} %</p>
<p id="weatherPrecip" className="spyData">Precipitation: {this.state.weatherData ? this.state.weatherData.current.precip : ""} mm</p>
</div>
)
}
}
export { Spy as Weather };
控制台(2 个更新,api 触发然后另一个更新):-
[HMR] Waiting for update signal from WDS...
2 Spy.js:18 update
Spy.js:23 api request resolved
Spy.js:18 update
解决方案
给定
componentDidUpdate(prevProps, prevState) {
console.log("update");
if (prevProps.location !== this.props.location) {
this.setState({location: this.props.location},()=>{
getWeather(this.state.location)
.then(data => {
console.log("api request resolved");
this.setState({ weatherData: data });
})
.catch(error =>
this.setState({ error: error.message }));
}
)}
else return;
}
和日志
2 Spy.js:18 update
Spy.js:23 api request resolved
Spy.js:18 update
是的,我看到三个渲染/重新渲染。
第一个“更新”是从何时
props.location
更改null
为某个值。条件测试prevProps.location !== this.props.location
解决true
了,因此采用快乐路径并使用位置更新状态。第二个“更新”现在是因为状态更新为
location
. 在上一次状态更新的同时,setState
已调用回调并获取天气。在承诺链的快乐路径中是日志“api request resolved”和另一个setState
.第三个“更新”再次来自状态更新,这次是
weatherData
.
正如您所知,将 props 存储在本地状态是 react 的一种反模式,只需发出副作用,例如在 props 更改时获取天气。也不建议在回调中链接状态更新,因为每个嵌套状态更新都会setState
延迟更新 1 个(或更多)渲染周期,并且会使调试更加困难。最好简单地处理它们。也不需要“void”返回,因为所有 JS 函数都有隐式返回,不需要返回任何实际值。componentDidUpdate
componentDidUpdate(prevProps, prevState) {
console.log("update");
if (prevProps.location !== this.props.location) {
if (location) {
// location prop changed and is truthy, get weather
getWeather(this.state.location)
.then(data => {
console.log("api request resolved");
this.setState({ weatherData: data });
})
.catch(error => this.setState({ error: error.message }));
}
}
}
这应该雕刻那些最初的“浪费”渲染周期之一,日志现在应该是
Spy.js:18 update
Spy.js:23 api request resolved
Spy.js:18 update
推荐阅读
- c++ - 与组合c ++中的其他类一起类
- python - 如何在python中使用随机枢轴实现快速排序
- c# - 将泛型类型发送到基类?
- stripe-payments - 为什么 Stripe testMode 工作但 liveMode 不工作?
- r - 关于 h2o.grid() 函数中的并行性的问题
- mysql - SQL 错误 [1054][42s22]: 未知列 'orderdetails.productCode in 'on 子句'
- html - 使用引导程序在同一行中添加文本和图像
- java - 所需的请求部分“文件”不存在,但设置可能正确
- bash - Bash 的“声明”的未记录的“-c”选项?
- mysql - 过程中更新查询的重复输入错误