猿问

useState 钩子有陈旧的数据

我正在使用useState钩子将下拉列表中的值设置为变量。在我的特殊情况下里面onDeviceIdChange,我设置setDeviceId到value它是由组件库我使用的是事件发出。value拥有我期望的正确值,但它不会deviceId立即更新。


我已经阅读了与此问题相关的各种帖子,最常见的解决方案似乎是将变量传递给第二个参数 useEffect


所以像这样


  useEffect(() => {

    fetchDeviceIds();

    console.log("call back for device id selection", deviceId);

  }, [deviceId]);

但这似乎只是fetchDeviceIds为我重复触发该函数,而从未真正调用更改处理程序。我已经尝试了一些变体,useEffect但无法在里面获得更新的值deviceId


下面是我的初始实现,没有放入deviceId第二个参数useEffect


import React, { useState, useEffect } from "react";

import axios from "axios";


import { Dropdown, Form, Input } from "semantic-ui-react";


const Example = props => {

  const [deviceId, setDeviceId] = useState("");

  const [hardware, setHardware] = useState([]);

  const [error, setError] = useState("");

  const [versionNum, setVersionNum] = useState("");

  const [isLoading, setIsLoading] = useState(true);


  async function fetchDeviceIds() {

    const url = "/api/hardware";

    try {

      const response = await fetch(url, {

        method: "GET"

      });


      if (!response.ok) {  

        setError(response.statusText);

      }


      const data = await response.json();

      console.log(data);   

      setHardware(data.hardware);

    } catch (error) {

      console.log("error catch", error);

      console.log("Handle networking errors", error.message);

    }

  }


  const versionUrl = "/api/versionUrl";

  const onDeviceIdChange = async (e, { value }) => {

    console.log("device id value --> ", value);

    setDeviceId(value);

    console.log(deviceId); //this won't update immediately


    if (!deviceId) {

      handleClear();

      return;

    }


      try {

        console.log("calling versionUrl");

        const response = fetch(versionUrl, {

          method: "POST",

          body: JSON.stringify({

            deviceId: deviceId

          }),

          headers: {

            "Content-Type": "application/json"

          }

        });



繁花如伊
浏览 212回答 2
2回答

RISEBY

onDeviceIdChange 应该是这样的:const onDeviceIdChange = async (e, { value }) => {    // code for validating value etc    setDeviceId(value);}其余的代码应该进入useEffect依赖于的钩子deviceId:useEffect(fetchId, [deviceId]);

饮歌长啸

setDeviceId(value);console.log(deviceId); //this won't update immediately because setDeviceId is asynchronous!setState() 不会立即改变 this.state 而是创建一个挂起的状态转换。调用此方法后访问 this.state 可能会返回现有值。无法保证对 setState 调用的同步操作,并且可能会批量调用以提高性能。React 不会更新状态,当您使用 console.log 时,您会获得先前的值在您的情况下,您可以使用valuefor all 同步操作,因为它是您正在设置的新值,或者您可以将 setState 下面的所有代码移动到 auseEffect更新从下面的代码和文档onChange={onDeviceIdChange}第二个参数将是形状的对象,{data: value} 因此您的参数value将始终未定义!const onDeviceIdChange = async (e, {value}) => {    console.log("device id value --> ", value);    console.log("device value from event --> ", e.target.value);    setDeviceId(value);  };useEffect(() => {    if (!deviceId) {      handleClear();      return;    }      try {        console.log("calling versionUrl");        const response = fetch(versionUrl, {          method: "POST",          body: JSON.stringify({            deviceId: deviceId          }),          headers: {            "Content-Type": "application/json"          }        });        if (!response.ok) {          setError(response.statusText);        }        const data = response.json();        console.log(data);        setVersionNum(data.version_num);        setIsLoading(false);      } catch (error) {        console.log("error catch", error);        console.log("Handle networking errors", error.message);      }    }},[deviceId])
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答