协程作为对useEffect的依赖

时间:2020-10-05 02:55:50

标签: reactjs

当前,我具有以下自定义挂钩:

function useSecurity() {
  const { getAccessTokenSilently } = useAuth0()

  const getAccessToken = async () => {
    return await getAccessTokenSilently()
  }
  
  const getAuthHeader = async () => {
    return { Authorization: `Bearer ${await getAccessToken()}` }
  }
   
  return { getAuthHeader }
}

在我使用它的页面中,我拥有:

const { getAuthHeader } = useSecurity()

useEffect(() => {
  async function fetchData() {
    ...
    }
  }
  fetchData()
}, [getAuthHeader])

此代码会导致无限循环页面加载,我认为是因为getAuthHeader是协程。我知道我不必将其包含在deps中(而忽略eslint警告),但是有没有办法我可以将其包含在deps中而不触发无限循环?

2 个答案:

答案 0 :(得分:0)

您的代码存在的问题是getAuthHeader就像一个钩子一样使用,但实际上是异步方法。您可以尝试像这样设置它:

function useSecurity() {
  const [token, setToken] = useState('');
  const { getAccessTokenSilently } = useAuth0();

  useEffect(() => {
    getToken = async () => {
      const token = await getAccessTokenSilently();
      setToken(token)
    }

    getToken();
  }, []);
   
  return { token }
}

这是将令牌存储在useSecurity钩子状态下,然后像这样使用它:

const { token } = useSecurity()

useEffect(() => {
  async function fetchData() {
    ...
    }
  }
  fetchData()
}, [token])

答案 1 :(得分:0)

使用大卫的建议使用useCallback()可以解决此问题。工作代码为:

function useSecurity() {
  const { getAccessTokenSilently } = useAuth0()

  const getAccessToken = async () => {
    return await getAccessTokenSilently()
  }
  
  const getAuthHeader = async () => {
    return { Authorization: `Bearer ${await getAccessToken()}` }
  }
   
  return { getAuthHeader: useCallback(getAuthHeader, []) }
}