不使用useState能否编写React函数组件?无setState如何触发重渲染?
React 只会在三种情况下触发组件重渲染:组件自身的 state 发生变更、父组件重渲染、组件订阅的 Context 发生变更。你直接用 let 定义的变量变更不会被 React 感知,自然不会触发视图更新,而且如果你的 let 变量是定义在函数组件内部的,每次组件重渲染时这些变量都会被重置为初始值,你在 load() 中修改的值根本无法持久保留,就算你把变量提到组件外部做成模块级变量,也只会出现多个组件实例共享变量的冲突问题,依然解决不了触发渲染的问题。
以下是不用拆成多个独立 state 的可行方案:
- 合并为单个 state 对象
你可以把所有相关变量打包成一个 state 统一管理,不需要给每个变量单独写 setter:
const [globalData, setGlobalData] = useState({ isTiketAdmin: null as string | null, jwt: null as string | null, organizationId: undefined as string | undefined, organization: undefined as OrganizationOut | undefined })
修改完变量后只要调用一次 setGlobalData 传入新的对象即可触发重渲染,和你现在的 load() 逻辑适配成本极低:
const load = () => { const newData = {...globalData} newData.isTiketAdmin = localStorage.getItem("isTiketAdmin"); newData.jwt = localStorage.getItem("jwt"); newData.userFbId = localStorage.getItem("userFbId"); const organizationList = JSON.parse( localStorage.getItem("organizationList") ?? "[]" ); newData.organizationId = getOrganizationFbIdFromEventId(eventId); if (newData.organizationId) { newData.organization = organizationList[newData.organizationId]; let event = newData.organization!.events[props.eventId]; // 其余逻辑 } // 最后调用一次setter触发重渲染 setGlobalData(newData) }
- useRef + 强制更新
如果你完全不想用 state 管理变量,可以用useRef存储所有变量,搭配一个强制更新的触发器实现需求:
// 先定义强制更新hook function useForceUpdate() { const [, trigger] = useState({}); return () => trigger({}); } // 组件内使用 const forceUpdate = useForceUpdate(); const dataRef = useRef({ isTiketAdmin: null as string | null, jwt: null as string | null, organizationId: undefined as string | undefined, organization: undefined as OrganizationOut | undefined }) const load = () => { // 直接修改ref下的属性 dataRef.current.isTiketAdmin = localStorage.getItem("isTiketAdmin"); dataRef.current.jwt = localStorage.getItem("jwt"); // 其余修改逻辑 // 修改完成后调用强制更新触发渲染 forceUpdate(); }
注意这个方案的弊端:不符合 React 响应式范式,React.memo、useMemo、useCallback 等性能优化API无法感知到 ref 的值变化,容易出现视图不更新的隐性bug,只适合逻辑简单的小型组件使用。
如果这些数据是多个组件通用的全局数据,更推荐你抽成全局 Context 或者状态管理库统一维护,避免每个组件重复读写 localStorage 的冗余逻辑。
内容的提问来源于stack exchange,提问作者János
相关产品推荐
相关产品推荐

