如何重构React函数组件中的Zustand Store代码以避免重复?
解决Zustand全局状态重复引用的重构方案
下面是两种实用的重构方式,彻底解决组件中重复编写状态选择逻辑的问题:
方案一:封装自定义Hook
把重复的状态和方法选择逻辑打包成一个自定义Hook,所有需要的组件直接调用这个Hook就行,不用每次写长长的解构代码。
步骤1:创建自定义Hook
// hooks/useUserState.js import useUserStore from '../stores/userStore'; export const useUserState = () => { return useUserStore(state => ({ token: state.token, isLogged: state.isLogged, categoryDetail: state.categoryDetail, loginUser: state.loginUser, logoutUser: state.logoutUser, setCategoryDetail: state.setCategoryDetail })); };
步骤2:组件中使用
// 任意业务组件 import { useUserState } from './hooks/useUserState'; const MyComponent = () => { // 按需解构需要的状态或方法 const { token, isLogged, loginUser } = useUserState(); return ( <div> {isLogged ? ( <p>当前Token:{token}</p> ) : ( <button onClick={() => loginUser('xxx-token')}>登录</button> )} </div> ); };
方案二:预定义选择器函数
把选择器逻辑单独抽成函数,放在store文件里统一维护,组件里调用useUserStore时直接传入这个预定义函数即可。
步骤1:在Store中定义选择器
// stores/userStore.js import { create } from 'zustand'; // 创建Store const useUserStore = create((set) => ({ token: '', isLogged: false, categoryDetail: null, loginUser: (userToken) => set({ token: userToken, isLogged: true }), logoutUser: () => set({ token: '', isLogged: false }), setCategoryDetail: (detail) => set({ categoryDetail: detail }) })); // 预定义全局选择器 export const selectUserState = (state) => ({ token: state.token, isLogged: state.isLogged, categoryDetail: state.categoryDetail, loginUser: state.loginUser, logoutUser: state.logoutUser, setCategoryDetail: state.setCategoryDetail }); export default useUserStore;
步骤2:组件中使用
// 任意业务组件 import useUserStore, { selectUserState } from './stores/userStore'; const MyComponent = () => { const userState = useUserStore(selectUserState); // 按需解构使用 const { categoryDetail, setCategoryDetail } = userState; return ( <div> <p>分类详情:{categoryDetail?.name}</p> <button onClick={() => setCategoryDetail({ name: '新分类' })}>更新分类</button> </div> ); };
额外优化:拆分细粒度Hook
如果不同组件需要的状态/方法不一样,可以拆分多个更细的自定义Hook,避免获取不需要的状态导致不必要的重渲染:
// hooks/useUserState.js import useUserStore from '../stores/userStore'; // 仅包含认证相关状态和方法 export const useAuthState = () => { return useUserStore(state => ({ token: state.token, isLogged: state.isLogged, loginUser: state.loginUser, logoutUser: state.logoutUser })); }; // 仅包含分类相关状态和方法 export const useCategoryState = () => { return useUserStore(state => ({ categoryDetail: state.categoryDetail, setCategoryDetail: state.setCategoryDetail })); };
组件按需导入对应的Hook即可,更灵活也更高效。
内容的提问来源于stack exchange,提问作者Pawan
相关产品推荐
相关产品推荐

