Javascript 如何在React上重新渲染相同的组件?

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

我正在使用api制作这个天气应用程序。所以,首先我要展示一个默认城市的天气。然后,当我选择其他城市时,该组件将再次渲染,以提供所选城市的天气数据。 到目前为止,我已经完成了我的项目:

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密钥。但我认为当我选择该选项时,响应可能会出现一些问题。我必须解决这个问题。你的代码在这里形成了一个无限循环,我的朋友注意到了这一点。