微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

好吧,我正在使用 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;

所以,我知道如果我想重新渲染,我必须使用 shouldComponentUpdate 生命周期方法。如果我想获得其他城市的天气响应,如何重新渲染相同的组件?或者我是否需要将状态作为道具传递给其他组件,然后我必须获取 api?需要帮助!

解决方法

你遇到的问题不是你需要重新渲染你的组件,而是当你的状态更新时你需要点击天气 API。为此,您可以确保在 componentDidUpdate 生命周期方法中调用 API。下面是一些更新的代码(并抽象了 API 调用以避免冗余代码)。

fetchWeatherData() {
  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
        });
      }
    );
}

componentDidMount() {
  this.fetchWeatherData();
}

componentDidUpdate(_,prevState) {
  if (prevState.lat !== this.state.lat || prevState.long !== this.state.long) {
    this.fetchWeatherData();
  }
}

在构造函数中,确保将 fetchWeatherData 绑定到 this

constructor(props) {
  // Existing constructor code here
  this.fetchWeatherData = this.fetchWeatherData.bind(this);
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。