Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在两个自定义挂钩之间共享状态?_Javascript_Reactjs_Axios_React Hooks - Fatal编程技术网

Javascript 如何在两个自定义挂钩之间共享状态?

Javascript 如何在两个自定义挂钩之间共享状态?,javascript,reactjs,axios,react-hooks,Javascript,Reactjs,Axios,React Hooks,我正在尝试从Spotify API获取数据。因为我需要一个访问令牌来完成这项工作,所以我构建了一个自定义钩子来解析来自服务器的URL中的令牌。 我还有另一个自定义钩子,其中包含对API的实际请求,该API将解析的令牌作为参数。两者都聚集在父钩子中 我无法做到这一点,因为令牌从未到达请求挂钩的作用域,所以它失败了。如果我解析令牌并在同一个钩子中发出请求,那么一切都会顺利进行。我打算为每个请求创建一个钩子,因为它不仅仅是一个,这就是为什么我想将令牌作为参数传递 令牌自定义挂钩 export defa

我正在尝试从Spotify API获取数据。因为我需要一个访问令牌来完成这项工作,所以我构建了一个自定义钩子来解析来自服务器的URL中的令牌。
我还有另一个自定义钩子,其中包含对API的实际请求,该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>  
  )   
}
导出默认函数Home(){
const token=useParseToken()
const{userData,isLoading,isError}=useFetchUserData(令牌);
如果(卸载)返回;
如果(isError)返回Oops!出现问题;
返回(
)   
}

您必须使用react的createContext api。 将令牌另存为上下文。无论你想在哪里使用它。
我想这会对您有所帮助。

您必须使用react的createContext api。 将令牌另存为上下文。无论你想在哪里使用它。
我想这会对您有所帮助。

在您的情况下,您正在自定义挂钩中的
useffect
hook中设置一个状态以设置令牌。但是,您可以在不等待效果运行的情况下从此钩子返回令牌,因此第一次调用
useFetchUserData
hook时,它将接收空字符串作为令牌。要解决这个问题,您必须实现
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();

在您的情况下,您正在自定义钩子中的
useffect
hook中设置一个状态来设置令牌。但是,您可以在不等待效果运行的情况下从此钩子返回令牌,因此第一次调用
useFetchUserData
hook时,它将接收空字符串作为令牌。要解决这个问题,您必须实现
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();

大家好@FedericoCastro,看看新的上下文API。听起来它非常适合您的用例!钩子的一部分是一个钩子,使上下文更容易使用!从您的示例代码来看,
const{token}=useTokenParser()
可能是错误的,应该是
const-token=useTokenParser()
,然后在
useFetchUserData
中,您应该正确处理
token==”
,因为第一次调用总是得到这种情况。非常感谢@hackape,它起了作用。我对解构兴奋过度。谢谢@Jared,也许是时候试试了!大家好@FedericoCastro,看看新的上下文API。听起来它非常适合您的用例!钩子的一部分是一个钩子,使上下文更容易使用!从您的示例代码来看,
const{token}=useTokenParser()
可能是错误的,应该是
const-token=useTokenParser()
,然后在
useFetchUserData
中,您应该正确处理
token==”
,因为第一次调用总是得到这种情况。非常感谢@hackape,它起了作用。我对解构兴奋过度。谢谢@Jared,也许是时候试试了!