在Reactjs中,useState无法在handleSubmit期间对数据进行setState

vddsk6oq  于 2022-12-03  发布在  React
关注(0)|答案(1)|浏览(119)

我正在努力琢磨一个愚蠢的错误,希望有人能帮助我更好地理解它。
setServerList(data.data)没有设置数据,当我尝试使用它时,它仍然是空的。

export const KernelUpdateSearch = (props: RouteComponentProps) => {
  const [serverList, setServerList] = useState<any>([]);

  // searchHost perform GET request to gannet for aggregate count
  const searchHost = async (hostRegex: string) => {
    try {
      const response = await fetch("URL", {
        mode: 'cors',
        method: 'GET',
        headers: requestHeaders
      });
      const data = await response.json();
      if (data.success === true) {
        if (data.data != null && (data.data.length > 0)) {
          setServerList(data.data);
        } else {
          setServerList([])
          console.log('no data found, status code: ', response.status);
        }
      } else {
          console.log("failed to query, error: ", data.error.message);
      }
    } catch (error) {
        console.log(error);
    }
  };

  const handleSubmit = (formInstance: FormEventReturn) => {
    handleChange(formInstance)
  };

  const handleChange = ({formData}: FormEventReturn) => {
    searchHost(formData.hostname);
    console.log(serverList);
  };

  return (
    <Card options={searchOptions}>
    <Form
      schema={searchSchema}
      uiSchema={uiSchema}
      onSubmit={handleSubmit}
    />
    </Card>
  );
};
tzdcorbm

tzdcorbm1#

我如何设置ServerList在handleChang事件后是持久的。
您有两个选项:

export const KernelUpdateSearch = (props: RouteComponentProps) => {
  const [serverList, setServerList] = useState<any>([]);

  // searchHost perform GET request to gannet for aggregate count
  const searchHost = async (hostRegex: string) => {
    let newServerList = [];
    try {
      const response = await fetch("URL", {
        mode: 'cors',
        method: 'GET',
        headers: requestHeaders
      });
      const data = await response.json();
      if (data.success === true) {
        if (data.data != null && (data.data.length > 0)) {
          newServerList = data.data;
        } else {
          console.log('no data found, status code: ', response.status);
        }

        setServerList(newServerList);
      } else {
        console.log("failed to query, error: ", data.error.message);
      }
    } catch (error) {
        console.log(error);
    }
    //
    // 1a - return new server list
    //
    return newServerList;
  };

  const handleSubmit = (formInstance: FormEventReturn) => {
    handleChange(formInstance)
  };

  const handleChange = ({formData}: FormEventReturn) => {
    searchHost(formData.hostname)
      .then(serverList => {
        //
        // 1b - get returned serverList or empty array
        //
        console.log(serverList);
      });
  };

  //
  // 2 - be notified when there are new servers
  //
  useEffect(() => {
    if (serverList.length > 0) {
       console.log(serverList);
    }
  }, [serverList]);

  return (
    <Card options={searchOptions}>
    <Form
      schema={searchSchema}
      uiSchema={uiSchema}
      onSubmit={handleSubmit}
    />
    </Card>
  );
};

编辑

无论您是否需要将serverList作为状态变量,都可以考虑使用此重构来提高可读性(即减少混淆):

// ---- utility can be imported from a different module ----

// searchHost perform GET request to gannet for aggregate count
const searchHost = async (hostRegex: string) => {
  let serverList = null;
  try {
    const response = await fetch("URL", {
      mode: 'cors',
      method: 'GET',
      headers: requestHeaders
    });
    const data = await response.json();

    if (data.success === true) {
      if (data.data != null && (data.data.length > 0)) {
        serverList = data.data;
      } else {
        serverList = [];
        console.log('no data found, status code: ', response.status);
      }
    } else {
      console.log("failed to query, error: ", data.error.message);
    }
  } catch (error) {
    console.log(error);
  }

  return serverList;
};

// -------------- React component below -------------

export const KernelUpdateSearch = (props: RouteComponentProps) => {
  const [serverList, setServerList] = useState<any>([]);
    
  const handleSubmit = async ({formData}: FormEventReturn) => {
    searchHost(formData.hostname)
      .then(newServerList => {
        // only update state if the returned value is non null
        if (newServerList) {
          setServerList(newServerList);
        }
      });
  };

  useEffect(() => {
    if (serverList.length > 0) {

       // new servers available!

       console.log(serverList);
    }
  }, [serverList]);

  return (
    <Card options={searchOptions}>
    <Form
      schema={searchSchema}
      uiSchema={uiSchema}
      onSubmit={handleSubmit}
    />
    </Card>
  );
};

通常,事件处理程序应该小而简单。在useEffect中包含一些东西是一种抽象,它允许您通过任何方式更新列表,并在一个中心位置进行处理。

相关问题