无法在 React 中通过 Axios 获取 accessToken

Unable to get accessToken via Axios in React

尝试从我的第一个 axios 调用中获取访问令牌并将其放入第二个。我的组件是这样的。

当我将 accessToken 记录到控制台时,它是一个空数组。当我 console.log(response.data) 我可以看到响应和我的 access_token

const Route = (props) => {
  const [accessToken, setAccessToken] = useState([]);
  const [route, setRoute] = useState([]);
  const [athlete, setAthlete] = useState([]);

  // get a refreshed token from strava
  useEffect(() => {
    axios({
      method: 'POST',
      url: 'https://www.strava.com/oauth/token',
      params: {
        client_id: process.env.GATSBY_STRAVA_CLIENT_ID,
        client_secret: process.env.GATSBY_STRAVA_CLIENT_SECRET,
        grant_type: 'refresh_token',
        refresh_token: process.env.GATSBY_STRAVA_REFRESH_TOKEN,
      },
    })
      .then((response) => {
        console.log(response.data);
        setAccessToken(response.data.access_token);

        console.log(accessToken);

        return axios({
          method: 'GET',
          url: `https://www.strava.com/api/v3/routes/${props.data.contentfulRoutes.slug}`,
          headers: {
            Authorization: `Bearer ${accessToken}`,
          },
        });
      })
      .then((response) => {
        console.log(response.data);
        setRoute(response.data);
        setAthlete(response.data.athlete);
      })
      .catch((err) => {
        console.log(err);
      });
  }, []);

这里的问题是你将令牌保持在状态中,一旦你在函数中间更新状态,值就不会同步更新,因此你仍然得到一个空数组。我会用 async/await 语法改写你的 useEffect ,如下所示:


useEffect(() => {
    const init = async () => {
        try {
            const firstResponse = await axios({
                method: 'POST',
                url: 'https://www.strava.com/oauth/token',
                params: {
                    client_id: process.env.GATSBY_STRAVA_CLIENT_ID,
                    client_secret: process.env.GATSBY_STRAVA_CLIENT_SECRET,
                    grant_type: 'refresh_token',
                    refresh_token: process.env.GATSBY_STRAVA_REFRESH_TOKEN,
                },
            })
            const token = firstResponse.data.access_token;
            setAccessToken(token) // Keep this line only if you need the token for something else later
            const secondResponse = await axios({
                method: 'GET',
                url: `https://www.strava.com/api/v3/routes/${props.data.contentfulRoutes.slug}`,
                headers: {
                    Authorization: `Bearer ${token}`,
                },
            });

            console.log(secondResponse.data);
            setRoute(secondResponse.data);
            setAthlete(secondResponse.data.athlete);
        } catch (e) {
            console.log(e);
        }
    }

    init();
}, []);

然后你可以摆脱你的 accessToken 状态,它是多余的并且不会在这里很好地为你服务(除非你需要保留它用于其他事情,在这种情况下你可以保留线 I评论)