
react 组件的 `usestate` 是局部状态,每次组件卸载再挂载都会重新初始化为初始值;若需保持状态不丢失,应使用 context + usereducer 构建全局状态管理方案。
在 React 中,useState(6) 创建的是组件内联的局部状态(local state),其生命周期完全绑定于该组件实例:当组件被卸载(如路由跳转、条件渲染移除),其所有 useState 值即被销毁;再次挂载时,会重新执行 useState(6),恢复初始值 6 —— 这正是你关闭又打开组件后数字“重置”的根本原因。这并非状态在每次 re-render 时自动更新,而是每次 mount 时重新初始化。
要实现跨组件、跨挂载周期的状态持久化,必须将状态提升至组件树的更高层级(即“全局状态”)。推荐使用 React 官方推荐的轻量级组合方案:createContext + useReducer。
✅ 正确做法:构建可共享的全局状态上下文
首先,创建一个状态管理模块(如 GlobalsProvider.jsx):
// GlobalsProvider.jsx
import { createContext, useReducer, useContext } from 'react';
const globalsInitialState = { number: 6 };
const actions = { UPDATE_NUMBER: 'UPDATE_NUMBER' };
export const globalsReducer = (state, action) => {
switch (action.type) {
case actions.UPDATE_NUMBER:
return { ...state, number: action.newNumber };
default:
return state;
}
};
export const GlobalsContext = createContext();
export const GlobalsProvider = ({ children }) => {
const [state, dispatch] = useReducer(globalsReducer, globalsInitialState);
const value = {
number: state.number,
updateNumber: (newNumber) => dispatch({ type: actions.UPDATE_NUMBER, newNumber })
};
return (
{children}
);
};然后,在应用根节点包裹该 Provider(通常在 App.jsx 或 main.jsx 中):
// App.jsx
import { GlobalsProvider } from './GlobalsProvider';
export default function App() {
return (
{/* 其他路由或组件 */}
);
}最后,在任意子组件中消费状态:
// Component1.jsx
import { useContext } from 'react';
import { GlobalsContext } from './GlobalsProvider';
export const Component1 = () => {
const { number, updateNumber } = useContext(GlobalsContext);
const handleClick = () => updateNumber(5);
return (
My number is {number}
);
};⚠️ 注意事项与最佳实践
- 不要滥用全局状态:仅对真正需要跨组件共享且有状态一致性要求的数据(如用户登录态、主题偏好、核心业务配置)使用此方案;普通 UI 状态仍应优先使用 useState。
- 避免直接修改 context value:始终通过 dispatch 触发状态变更,确保可追溯性与调试友好性。
- 性能提示:useContext 本身不会导致不必要的 re-render,但若 value 对象在每次渲染中被重新创建(如未用 useMemo 包裹),可能引发下游组件误判为状态变化。本例中因 value 在 GlobalsProvider 内稳定定义,无需额外优化。
- 进阶替代方案:对于复杂应用,可考虑 Zustand、Jotai 或 Redux Toolkit,它们在 DX 和性能上做了进一步封装,但 Context + useReducer 已足够应对大多数中等规模场景。
通过这种方式,number 不再属于某个组件的私有财产,而是整个应用上下文中的共享事实(single source of truth),无论组件如何卸载/重挂载,只要 Provider 持续存在,状态就持续有效。









