【问题标题】:Why is my ReactJS component state change not triggering a re-render?为什么我的 ReactJS 组件状态更改不会触发重新渲染?
【发布时间】:2021-03-19 19:57:47
【问题描述】:

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

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 开发工具中的组件状态中看到我自己的纬度/经度坐标。

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

【问题讨论】:

    标签: reactjs state rerender


    【解决方案1】:

    你的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]);
    

    【讨论】:

    • 非常感谢。这解决了问题。我将对 useEffect 功能进行更多研究,以确保我将来可以正确使用它!谢谢你的简洁解释。
    猜你喜欢
    • 1970-01-01
    • 2020-07-26
    • 2020-08-18
    • 2020-08-12
    • 2020-11-04
    • 2022-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多