React自定义Hook中useState状态更新未同步至所有组件
问题原因
你搞错了React自定义Hook的作用:自定义Hook只用来复用状态逻辑,不会自动共享状态本身。
每次你在不同组件里调用useTheme(),都会在当前组件里独立执行一次useState("dark"),生成一份完全独立、和其他组件互不干扰的状态。你的代码里一共生成了3份完全无关的themeName状态:
- ThemeSwitcher组件内部持有1份:点击按钮时你调用的set方法,只会修改这一份状态,所以只有这个组件会重渲染、显示更新后的值
- Other组件内部持有1份:初始值是dark,从来没有被修改过,所以一直显示dark
- App组件内部持有1份:初始值是dark,从来没有被修改过,所以一直显示dark
这就是为什么只有点击按钮的组件能拿到更新后的值,其他组件完全没变化——它们根本没用同一份状态。
修复方法
要实现跨组件共享同一份主题状态,用React的Context API做全局状态下发即可,修复后的可运行代码如下:
import { useState, createContext, useContext } from "react"; // 创建全局主题上下文 const ThemeContext = createContext(null); // 顶层Provider组件,持有唯一的共享主题状态 function ThemeProvider({ children }) { const [themeName, setThemeName] = useState("dark"); const toggleTheme = () => { setThemeName(prev => prev === "dark" ? "light" : "dark"); }; return ( <ThemeContext.Provider value={{ themeName, toggleTheme }}> {children} </ThemeContext.Provider> ); } // 重写useTheme,直接从上下文取共享状态,不再单独创建useState function useTheme() { const contextValue = useContext(ThemeContext); if (!contextValue) { throw new Error("useTheme 只能在 ThemeProvider 包裹的组件内使用"); } return contextValue; } function Other() { const { themeName } = useTheme(); return <div>{themeName}</div>; } function ThemeSwitcher() { const { themeName, toggleTheme } = useTheme(); return ( <> <button onClick={toggleTheme}>BUTTON</button> {themeName} </> ); } function App() { const { themeName } = useTheme(); return ( <div> <ThemeSwitcher /> <Other /> <div>{themeName}</div> </div> ); } // 根组件用Provider包裹,所有内部子组件都能访问同一份主题状态 export default function Root() { return ( <ThemeProvider> <App /> </ThemeProvider> ); }
补充一个原代码的小问题:判断主题值时你用了非严格相等==,React状态判断建议统一用严格相等===,避免隐式类型转换导致的判断错误。
内容的提问来源于stack exchange,提问作者Zeal Iskander
相关产品推荐
相关产品推荐

