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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 02:15:39