我建立一个天气应用程序,我正在寻找一些建议,用于基于从父组件发送从父组件的异步调用后道具子组件更新状态的最佳实践。
我有一个父组件,使异步/ AWAIT在componentDidMount()
方法调用到navigator.geolocation
并返回纬度,我想送孩子组件作为道具经度。然后,在子组件我需要做的异步/的await调用使用lat和长从道具OpenWeatherMap API。那么我需要使用setState()
到response
。因为它的父异步之前安装,我不能在孩子使用componentDidMount()
/等待调用返回。
问题是应用程序流:父组件坐骑和渲染,送道具,孩子一样null
。子组件坐骑和呈现与null
道具。然后,异步/ AWAIT返回父的响应,设置和lat
从long
响应在componentDidMount()
到状态,父重新呈现,并用正确的值作为lat
和long
发送道具孩子。儿童组件更新与道具正确的值。现在,在这一点上,我需要那些道具setState()
,但是我显然不能做到这一点在componentDidUpdate()
无需重新渲染成一个无限循环。
那么,什么是完成这一任务的好办法?
父组件:
class Container extends React.Component {
state = {
cityState: {
city: "",
state: ""
},
latLong: {
lat: null,
long: null
}
};
componentDidMount() {
this.getCityAndState();
}
getCityAndState() {
let latlng = "";
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(async position => {
latlng = `${position.coords.latitude},${position.coords.longitude}`;
const response = await googleGeolocation.get(
`json?latlng=${latlng}&location_type=APPROXIMATE&result_type=locality&key=${APIkey}`
);
this.setState({
cityState: {
city: response.data.results[0].address_components[0].long_name,
state: response.data.results[0].address_components[2].short_name
},
latLong: {
lat: position.coords.latitude,
long: position.coords.longitude
}
});
});
}
}
render() {
return (
<div className="container">
<LocationTime location={this.state.cityState} />
<Forecast location={this.state.latLong} />
</div>
);
}
}
子组件:
class Forecast extends React.Component {
state = {
today: {},
secondDay: {},
thirdDay: {},
fourthDay: {},
fifthDay: {}
};
async componentDidUpdate() {
********** A bunch of logic in here to extract Weather API response
into 5 separate arrays which will each be sent to the <Day /> child components
after setting the state to those arrays(which doesn't work in this
life-cycle method, currently) **********
}
render() {
return (
<div className="forecast">
<Day forecast={this.state.today} />
<Day forecast={this.state.secondDay} />
<Day forecast={this.state.thirdDay} />
<Day forecast={this.state.fourthDay} />
<Day forecast={this.state.fifthDay} />
</div>
);
}
}
附:我总是问一些具有相当简单的答案最终费解的问题,哈哈
您可以使用componentWillReceiveProps
生命周期方法。
第一子组件使一些道具像lat
和lng
为空,那么你可以这样做:
async componentWillReceiveProps(nextProps) {
if ( this.props.lat !== nextProps.lat || this.props.lng !== nextProps.lng ) {
const response = await YourAPICall(nextProps.lat, nextProps.lng)
this.setState(/* set your things here */)
}
}
显然,这只是一个大纲...
不知道为什么你使用异步/等待,而不是一个正常的获取/ Axios公司电话。为了防止进入你的componentDidUpdate
一个无限循环,正如你所说,你需要运行一个条件语句,是这样的:
componentDidUpdate(prevState){
if (this.props.propertyYouWantToCheck !== prevState.propertyYouWantToCheck){
// set your state/logic here
}
}
你也可能要考虑只使用在父组件获取数据,并将其传递到子组件。