我正在构建一个天气应用程序,我正在寻求一些关于在子组件中根据父组件从异步调用发送的props更新状态的最佳实践建议。
我有一个父组件,在componentDidMount()方法中进行了异步/等待调用navigator.geolocation,并返回纬度和经度,我想将其作为props发送到子组件。然后,在子组件中,我需要使用来自props的lat和long对OpenWeatherMap API进行异步/等待调用。然后,我需要使用响应来setState()。我不能在子组件中使用componentDidMount(),因为它在父异步/等待调用返回之前挂载。
问题是应用程序流程:父组件挂载并呈现,将props作为null发送到子组件。子组件挂载并呈现具有null props。然后,异步/等待在父级返回响应,在componentDidMount()中将lat和long设置为状态,父级重新呈现并发送正确值的props作为lat和long到子级。子组件使用props中的正确值进行更新。现在,在这一点上,我需要使用这些props来setState(),但是我显然不能在componentDidUpdate()中执行它,否则会重新呈现成无限循环。
那么,完成此任务的好方法是什么?
PARENT COMPONENT:
我有一个父组件,在componentDidMount()方法中进行了异步/等待调用navigator.geolocation,并返回纬度和经度,我想将其作为props发送到子组件。然后,在子组件中,我需要使用来自props的lat和long对OpenWeatherMap API进行异步/等待调用。然后,我需要使用响应来setState()。我不能在子组件中使用componentDidMount(),因为它在父异步/等待调用返回之前挂载。
问题是应用程序流程:父组件挂载并呈现,将props作为null发送到子组件。子组件挂载并呈现具有null props。然后,异步/等待在父级返回响应,在componentDidMount()中将lat和long设置为状态,父级重新呈现并发送正确值的props作为lat和long到子级。子组件使用props中的正确值进行更新。现在,在这一点上,我需要使用这些props来setState(),但是我显然不能在componentDidUpdate()中执行它,否则会重新呈现成无限循环。
那么,完成此任务的好方法是什么?
PARENT COMPONENT:
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>
);
}
}
附言:我总是问一些复杂的问题,最终得到的答案却相当简单,哈哈。