Javascript 如何在React上重新渲染相同的组件?
我正在使用api制作这个天气应用程序。所以,首先我要展示一个默认城市的天气。然后,当我选择其他城市时,该组件将再次渲染,以提供所选城市的天气数据。 到目前为止,我已经完成了我的项目:Javascript 如何在React上重新渲染相同的组件?,javascript,reactjs,react-lifecycle,Javascript,Reactjs,React Lifecycle,我正在使用api制作这个天气应用程序。所以,首先我要展示一个默认城市的天气。然后,当我选择其他城市时,该组件将再次渲染,以提供所选城市的天气数据。 到目前为止,我已经完成了我的项目: const initialDivisionId = "3"; const getDivision = (divisionId) => { return divisions.find((division) => division.id === divisionId); }; c
const initialDivisionId = "3";
const getDivision = (divisionId) => {
return divisions.find((division) => division.id === divisionId);
};
class Weather extends React.Component {
constructor(props) {
super(props);
const division = getDivision(initialDivisionId);
this.state = {
divisionId: initialDivisionId,
lat: division.lat,
long: division.long,
currentWeatherData: [],
hourlyWeatherData: [],
dailyWeatherData: []
};
}
onDivisionChange = (event) => {
const divisionId = event.target.value;
const { lat, long } = getDivision(divisionId);
this.setState({
divisionId: event.target.value,
lat: lat.lat,
long: long.long
});
};
componentDidMount() {
fetch(
`https://api.openweathermap.org/data/2.5/onecall?lat=${this.state.lat}&lon=${this.state.long}&units=metric&exclude=alerts&appid={api_key}`
)
.then((res) => res.json())
.then(
(result) => {
this.setState({
currentWeatherData: result.current,
hourlyWeatherData: result.hourly[0],
dailyWeatherData: result.daily[0]
});
},
(error) => {
console.log(error);
this.setState({
error
});
}
);
}
render() {
console.log(this.state.currentWeatherData);
console.log(this.state.hourlyWeatherData);
console.log(this.state.dailyWeatherData);
return (
<div>
<Title />
<Select
variant="filled"
w="30%"
placeholder="Select option"
value={this.state.divisionId}
onChange={this.onDivisionChange}
>
{divisions.map((division) => (
<option key={division.id} value={division.id}>
{division.name}
</option>
))}
</Select>
<div>
<Stack spacing={6}>
<Heading color="tomato" size="4xl">
{this.state.currentWeatherData.dt}
</Heading>
<Heading color="gray" size="3xl">
{this.state.currentWeatherData.temp}
</Heading>
<Heading color="blue" size="2xl">
{this.state.hourlyWeatherData.pressure}
</Heading>
<Heading color="black" size="xl">
{this.state.hourlyWeatherData.temp}
</Heading>
<Heading color="black" size="lg">
{this.state.dailyWeatherData.clouds}
</Heading>
<Heading color="yellow" size="md">
{this.state.dailyWeatherData.humidity}
</Heading>
</Stack>
</div>
</div>
);
}
}
const Title = () => {
return (
<Text align="center">
<Heading size="xl">Weather App</Heading>
</Text>
);
};
function App() {
return (
<ChakraProvider>
<Weather />
</ChakraProvider>
);
}
export default App;
const initialDivisionId=“3”;
const getDivision=(division id)=>{
返回divisions.find((division)=>division.id==divisionId);
};
类。组件{
建造师(道具){
超级(道具);
const division=getDivision(initialdivision id);
此.state={
divisionId:initialDivisionId,
lat:division.lat,
龙:除法,龙,
currentWeatherData:[],
小时天气数据:[],
每日天气数据:[]
};
}
onDivisionChange=(事件)=>{
const divisionId=event.target.value;
const{lat,long}=getDivision(divisionId);
这是我的国家({
分区ID:event.target.value,
lat:lat.lat,
朗:朗,朗
});
};
componentDidMount(){
取回(
`https://api.openweathermap.org/data/2.5/onecall?lat=${this.state.lat}&lon=${this.state.long}&units=metric&exclude=alerts&appid={api_key}`
)
.然后((res)=>res.json())
.那么(
(结果)=>{
这是我的国家({
currentWeatherData:result.current,
hourlyWeatherData:结果。每小时[0],
dailyWeatherData:结果。每日[0]
});
},
(错误)=>{
console.log(错误);
这是我的国家({
错误
});
}
);
}
render(){
console.log(this.state.currentWeatherData);
console.log(this.state.hourlyWeatherData);
console.log(this.state.dailyWeatherData);
返回(
{divisions.map((division)=>(
{division.name}
))}
{this.state.currentWeatherData.dt}
{this.state.currentWeatherData.temp}
{this.state.hourlyWeatherData.pressure}
{this.state.hourlyWeatherData.temp}
{this.state.dailyWeatherData.clouds}
{this.state.dailyWeatherData.湿度}
);
}
}
常量标题=()=>{
返回(
天气应用程序
);
};
函数App(){
返回(
);
}
导出默认应用程序;
所以,我知道如果我想重新渲染,我必须使用shouldcomponentupdatelifecycle方法。如果我想获得其他城市的天气响应,如何重新渲染相同的组件?或者我需要将状态作为道具传递给其他组件,然后获取api吗?需要帮助 您遇到的问题不是您需要重新渲染组件,而是您需要在状态更新时使用天气API。您可以通过确保在
componentdiddupdate
生命周期方法中调用API来实现这一点。下面是一些更新后的代码(并对API调用进行了抽象以避免冗余代码)
fetchWeatherData(){
取回(`https://api.openweathermap.org/data/2.5/onecall?lat=${this.state.lat}&lon=${this.state.long}&units=metric&exclude=alerts&appid={api_key}`
)
.然后((res)=>res.json())
.那么(
(结果)=>{
这是我的国家({
currentWeatherData:result.current,
hourlyWeatherData:结果。每小时[0],
dailyWeatherData:结果。每日[0]
});
},
(错误)=>{
console.log(错误);
这是我的国家({
错误
});
}
);
}
componentDidMount(){
这是fetchWeatherData();
}
componentDidUpdate(ux,prevState){
if(prevState.lat!==this.state.lat | | prevState.long!==this.state.long){
这是fetchWeatherData();
}
}
在构造函数中,确保将fetchWeatherData
绑定到this
构造函数(道具){
//此处的现有构造函数代码
this.fetchWeatherData=this.fetchWeatherData.bind(this);
}
如果设置状态,则组件应重新渲染,而无需对其执行任何其他操作。你试过用新的城市信息来设置州吗?这是什么意思?每当状态发生变化时,您的组件都将重新呈现。每次调用this.setState
时,如果根据更改的数据发生DOM更改,则组件将重新呈现。啊,我看到了您的问题,您的API调用仅在componentDidMount
中进行,因此,它只会在您的组件挂载时获取数据。您要做的是将它放在componentdiddupdate
中。若要尝试避免冗余代码,您可以将其放入自己的方法中。@Nick好的,那么提取应该在componentDidmount中吗?它会抛出一个未处理的运行时错误TypeError:无法读取未定义的
的属性“0”。您可能必须在提取调用的返回过程中进行一些疑难解答。该错误告诉我,在某个时间点,从fetch调用返回的结果中没有result.hourly
或result.daily
。例如,如果您提供了一个错误的lat/lon,那么API是否会有不同类型的返回?(同时确保API键包含正确。现在我复制了您在问题中使用它的方式,但它看起来应该是一个模板文本变量${API_key}
,而不是当前的形式(没有美元符号)很明显,我输入了正确的api密钥。但我认为当我选择该选项时,响应可能会出现一些问题。我必须解决这个问题。你的代码在这里形成了一个无限循环,我的朋友注意到了这一点。