为什么我的 ReactJS 组件状态更改没有触发重新渲染?

Why is my ReactJS component state change not triggering a re-render?

我有一个带有以下构造函数的 ReactJS class 组件:

constructor(props) {
      super(props);
      this.state = {
        // Defaults (London)
        latitude: 51.509865,
        longitude: -0.118092,
        userAddress: null
      };
      this.getCoordinates = this.getCoordinates.bind(this);
    }

然后我尝试获取用户坐标并将它们保存到状态:

    // On component initialisation, get the users location in co-ordinates and set the state accordingly
    componentDidMount() {
      if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(this.getCoordinates, this.handleLocationError);
      } else {
        alert("Geolocation is not supported by this browser.");
      }
    }
    
    getCoordinates(position) {
      this.setState({
        latitude: position.coords.latitude,
        longitude: position.coords.longitude
      })
    }

我将用户坐标传递给一个子函数,该子函数在屏幕上呈现一张天气卡,其中包含用户所在位置的当前温度。

渲染函数:

    render() {
      (some code)
        <div><CreateWeatherCard lat={this.state.latitude} long={this.state.longitude} /></div>
       (some code)
    }

创建天气卡片的函数将用户坐标作为道具,在 POST 请求 API 调用中使用它们,然后应该在用户当前位置显示温度屏幕

function CreateWeatherCard(props) {
  const classes = cardStyles();
  let [currentTemp, setCurrentTemp] = React.useState([]);

    // console.log(props.lat)

  React.useEffect(() => {
    async function fetchData() {
      const request = await axios.post('/weatheratcoords/', {
        lat: props.lat,
        long: props.long
      });
      // console.log(request);
      // console.log(request.data.currentTemp);
      setCurrentTemp(request.data.currentTemp);
      return request;
    }
    fetchData();
  }, []);

   return
     blah blah

但由于我是 运行 本地后端,我可以看到我只收到一个 API 状态构造函数的默认坐标调用。我再也没有接到更新坐标的第二个电话。我知道状态正在成功更新,因为我可以在 React 开发工具中的组件状态中看到我自己的 lat/long 坐标。

我的理解是状态变化应该触发重新渲染,这反过来应该创建一个新的 API 具有正确用户坐标的调用?有人可以帮助我理解为什么这没有发生吗?谢谢!

你的useEffect()有问题。

你是这样写的:

 React.useEffect(() => {
    async function fetchData() {
      const request = await axios.post('/weatheratcoords/', {
        lat: props.lat,
        long: props.long
      });
      // console.log(request);
      // console.log(request.data.currentTemp);
      setCurrentTemp(request.data.currentTemp);
      return request;
    }
    fetchData();
  }, []);

第二个参数为空数组,表示useEffect()只执行一次


解决方案

当你使用 props 将值传递给子组件时,所以当 props 改变时,useEffect() 将被执行。为此,将 useEffect() 数组中的道具作为第二个参数传递。

像这样:

 React.useEffect(() => {
    async function fetchData() {
      const request = await axios.post('/weatheratcoords/', {
        lat: props.lat,
        long: props.long
      });
      // console.log(request);
      // console.log(request.data.currentTemp);
      setCurrentTemp(request.data.currentTemp);
      return request;
    }
    fetchData();
  }, [props]);