繁体   English   中英

如何调用取决于更新的 state 的回调?

[英]How can I call a callback that depends on an updated state in react?

function useRequest() {

  const [accessToken, setAccessToken] = useState(42);
  const [refreshToken, setRefreshToken] = useState(7);
  
  const request = async (url) => {
    try {
      const res = await axios.get(url, { Headers: { Auth: accessToken } });
    } catch (error) {
      if (error.response.status === 401) {
        refresh(() => request(url));
      }
    }
  }
  
  const refresh = async (callback) => {
    const res = await axios.get("myserver.com", { params: { refreshToken }});
    setAccessToken(res.data.accessToken);
    callback()
  }
  
  return request;

}

所以我想调用这个 api 并在它过期时刷新访问令牌。 问题是,当我在刷新 function 中设置访问令牌 state 时,使用旧的 state 调用回调,因为 setState 是异步的。 在其他情况下,我可以只使用 useEffect 但我不确定在这种情况下该怎么做。

如果您出于某种原因不想使用useEffect ,另一种选择是将您设置的 state 传递给request function,以便它不依赖于外部变量。

const request = async (url, accessToken = 42) => {
    try {
        const res = await axios.get(url, { Headers: { Auth: accessToken } });
    } catch (error) {
        if (error.response.status === 401) {
            refresh((accessToken) => request(url, accessToken));
        }
    }
}

const refresh = async (callback) => {
    const res = await axios.get("myserver.com");
    const { accessToken } = res.data;
    setAccessToken(accessToken);
    callback(accessToken);
}

我认为您想将accessToken存储在ref中而不是state中。

官方反应文档: https://reactjs.org/docs/hooks-reference.html#useref

useState是异步的,因为 React 假设 state 与 UI 相关,因此 state 更新与 React 渲染生命周期相耦合。

更新ref是同步的,对于不需要触发 UI 更新的持久化数据来说是一个不错的选择。

您的代码,但使用useRef

function useRequest() {

  const accessTokenRef = useRef(42);
  const [refreshToken, setRefreshToken] = useState(7);
  
  const request = async (url) => {
    try {
      const res = await axios.get(url, { Headers: { Auth: accessTokenRef.current } });
    } catch (error) {
      if (error.response.status === 401) {
        refresh(() => request(url));
      }
    }
  }
  
  const refresh = async (callback) => {
    const res = await axios.get("myserver.com", { params: { refreshToken }});
    accessTokenRef.current = res.data.accessToken;
    callback()
  }
  
  return request;

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM