React useState和useEffect状态落后一步

时间:2020-09-16 01:53:31

标签: javascript reactjs typescript react-hooks

我知道出于性能原因,状态更新是异步的并且是批量的。知道我选择使用useState()和useEffect()等待状态更新,然后对其执行操作。我的问题是我的状态始终落后于应该达到的状态。

const myFunctionalComponent: React.FC<Props> = (
  props: Props
) {
  const [lastRequestURL, setLastRequestURL] = useState<string>();

  useEffect(() => {
    if (lastRequestURL !== undefined) {
      (async () => {
        try {
          await webRequest(lastRequestURL);
        } catch (e) {
          setResponse(undefined);
        }
      })();
    }
  }, [lastRequestURL]);

 const webRequest = async (value: string) => {
  const response = await axios.get(createURL(`/myServer/website-to-query?url=${encodeURIComponent(value)}`);
  // I do operations server-side with value (a URL) and then send a response back
  if (response) {
    if (newResponse.data.URL &&
              lastRequestURL !== newResponse.data.URL) { // I send the URL back in the data
      return; // This guard check is the key functionality that I want to work. 
      // I check the URL that was used for the request vs. the most recent 
      // URL that a handle change call has received. If it is not the same, 
      // that means that I've don't want to display anything as that 
      // info from the server is already invalid with the front-end's new state
    }
    // Do stuff that is valid for the front-end b/c we passed the check
  }
}

const handleChange = async (value: string): Promise<void> => {
    setLastRequestURL(value);
};

谢谢您的帮助。

1 个答案:

答案 0 :(得分:0)

免责声明:我认为这不是一个好习惯,但是如果您确实需要¯\ _(ツ)_ /¯,也可以看看axios的请求{{ 3}}

您可以使用ref来存储可变变量,因此它与反应生命周期无关

const myFunctionalComponent: React.FC<Props> = (
  props: Props
) {
  const lastRequestURL = useRef<string>(undefined);

  const webRequest = async (value: string) => {
    const response = await axios.get(createURL(`/myServer/website-to-query?url=${encodeURIComponent(value)}`);
    // I do operations server-side with value (a URL) and then send a response back
    if (response) {
      if (newResponse.data.URL &&
                lastRequestURL.current !== newResponse.data.URL) { // I send the URL back in the data
        return; // This guard check is the key functionality that I want to work. 
        // I check the URL that was used for the request vs. the most recent 
        // URL that a handle change call has received. If it is not the same, 
        // that means that I've don't want to display anything as that 
        // info from the server is already invalid with the front-end's new state
      }
      // Do stuff that is valid for the front-end b/c we passed the check
    }
  }

  const handleChange = async (value: string): Promise<void> => {
    await webRequest(value);
    lastRequestURL.current = value;
  };
}

cancelation