Как я могу разделить состояние между двумя пользовательскими хуками? - PullRequest
1 голос
/ 01 мая 2019

Я пытаюсь получить данные из 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>  
  )   
}

Ответы [ 2 ]

0 голосов
/ 01 мая 2019

Что происходит в вашем случае, так это то, что вы устанавливаете состояние в 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();
0 голосов
/ 01 мая 2019

Вы должны использовать createContext API для реагирования.Сохраните свой токен как контекст.и использовать его там, где вы хотите.Я думаю этот репозиторий поможет вам.

...