簡體   English   中英

如何在兩個自定義鈎子之間共享狀態?

[英]How can I share state between two custom hooks?

我正在嘗試從Spotify API獲取數據。 由於我需要訪問令牌來執行此操作,因此我構建了一個自定義鈎子,以從服務器的URL中解析令牌。
我還有另一個自定義鈎子,具有對API的實際請求,該請求將已解析的令牌作為參數。 兩者都聚集在父掛鈎中。

我無法完成這項工作,因為令牌從未達到請求掛鈎的范圍,因此失敗了。 如果我解析令牌並在同一鈎子內發出請求,則一切正常。 我打算為每個請求創建一個鈎子,因為它不僅是一個請求,這就是為什么我想將令牌作為參數傳遞的原因。

令牌自定義鈎

export default () => {
  const [ token, setToken ] = useState('')
  useEffect(() => {
    const { access_token } = queryString.parse(window.location.search)
    return setToken(access_token)
  }, [])
  return token
}

請求掛鈎

export default function useFetchUserData(token) {
  //state
  const initialUserState = {
    display_name: '',
    external_url: '',
    images: ''
  }
  const [ userData, setUserData ] = useState(initialUserState)
  const [ isLoading, setIsLoading ] = useState(false)
  const [ isError, setIsError ] = useState(false)

  useEffect(() => {
    async function getUserData() {
      setIsLoading(true);
      setIsError(false);

      const spotify = axios.create({
        baseURL: 'https://api.spotify.com/v1/me',
        headers: {
          'Authorization': `Bearer ${token}`
        }
      })
      try {
        const userRes = await spotify('/')
        .then( res => { return res.data });

        setUserData({
          display_name: userRes.display_name,
          external_url: userRes.external_urls.spotify,
          images: userRes.images[0].url
        })
      } catch (error) {
          setIsError(true)
      }
      setIsLoading(false);
    }
    getUserData();
  }, [])

  const data = {
    userData,
    isLoading,
    isError
  }
  return data
}

父母鈎

export default function Home() {

  const  token = useParseToken()
  const { userData, isLoading, isError } = useFetchUserData(token);

  if (isLoading) return <BarLoader />;
  if (isError) return <div>Oops! something went wrong</div>;

  return (
    <Fragment>
      <Header userData={userData}/>
    </Fragment>  
  )   
}

您必須使用react的createContext api。 將令牌另存為上下文。 並在您想要的任何地方使用它。 我認為該存儲庫將為您提供幫助。

在這種情況下,您將在自定義鈎子中的useEffect鈎子中設置狀態以設置令牌。 但是,您可以從該掛鈎返回令牌,而無需等待效果運行,因此,第一次調用useFetchUserData掛鈎時,它將接收空字符串作為令牌。 為了解決這個問題,您必須實現useFetchUserData掛鈎,以在令牌可用或令牌更改后立即運行

export default function useFetchUserData(token) {
  //state
  const initialUserState = {
    display_name: '',
    external_url: '',
    images: ''
  }
  const [ userData, setUserData ] = useState(initialUserState)
  const [ isLoading, setIsLoading ] = useState(false)
  const [ isError, setIsError ] = useState(false)

  useEffect(() => {
    async function getUserData() {
      setIsLoading(true);
      setIsError(false);

      const spotify = axios.create({
        baseURL: 'https://api.spotify.com/v1/me',
        headers: {
          'Authorization': `Bearer ${token}`
        }
      })
      try {
        const userRes = await spotify('/')
        .then( res => { return res.data });

        setUserData({
          display_name: userRes.display_name,
          external_url: userRes.external_urls.spotify,
          images: userRes.images[0].url
        })
      } catch (error) {
          setIsError(true)
      }
      setIsLoading(false);
    }
    if(token !== '' || token !== null) {
       getUserData();
    }
  }, [token])

  const data = {
    userData,
    isLoading,
    isError
  }
  return data
}

另外,由於useParseToken返回令牌,因此您在使用時無需對其進行解構

const token = useParseToken();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM