You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React TokenContext中useEffect无法存储Spotify登录token问题

问题原因

现有代码逻辑失效是三个点导致的:

  • 哈希解析逻辑无容错:手写的字符串分割逻辑中,一旦find()未匹配到access_token字段,后续调用.split("=")会直接抛出类型错误,中断整个useEffect执行链,后续存储token、清空URL哈希、更新全局状态的代码全部不会运行,授权参数会一直残留在URL上。
  • 判断顺序不合理:优先读取localStorage中的值做分支判断,若本地残留空字符串、过期token等无效值,会直接跳过URL哈希解析步骤,无法处理Spotify授权回调后新返回的有效token。
  • React 18严格模式下effect会重复执行挂载-卸载流程,原有逻辑未做幂等处理,容易出现状态更新冲突。
修复后的代码

直接替换原有TokenContext.js的内容即可:

import React, { useEffect, useState } from "react";

// token is the state
// logOut and logIn is a function for changing the state.
export const TokenContext = React.createContext({
    token: "",
    logOut: () => { },
    logIn: () => { }
});

function getInitialState() {
    return window.localStorage.getItem('token') || ""
}

const TokenContextProvider = (props) => {
    const [token, setToken] = useState(getInitialState);

    useEffect(() => {
        const hash = window.location.hash;
        if (!hash) return;

        // 用原生API安全解析哈希参数,避免字符串分割的容错问题
        const hashParams = new URLSearchParams(hash.substring(1));
        const accessToken = hashParams.get("access_token");

        if (accessToken) {
            window.localStorage.setItem("token", accessToken);
            setToken(accessToken);
        }

        // 清空URL上的授权参数,兼容不同浏览器的hash表现
        window.history.pushState("", document.title, window.location.pathname + window.location.search);
    }, []);

    const logIn = (token) => {
        window.localStorage.setItem("token", token);
        setToken(token);
    };

    const logOut = () => {
        setToken("")
        window.localStorage.removeItem("token")
    }

    return (
        <TokenContext.Provider
            value={{ token, logOut, logIn }}
        >
            {props.children}
        </TokenContext.Provider>
    );
};

export default TokenContextProvider;
修复点说明
  • 用原生URLSearchParams做哈希参数解析,自带容错能力,不会因为参数格式、字段缺失问题抛错中断逻辑
  • 调整判断逻辑:优先解析当前URL的哈希参数,只要拿到有效access_token就覆盖更新本地存储和全局状态,不会被本地残留的无效值跳过解析流程
  • 改用history.pushState清空URL参数,避免原来设置window.location.hash = ""可能残留#符号的问题,彻底清除URL上的授权返回参数
  • 补全logIn方法的持久化逻辑,修复原逻辑中手动调用登录方法时只更新内存状态、刷新页面就丢失登录态的问题

内容的提问来源于stack exchange,提问作者CesarDlr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 07:27:17