简体   繁体   English

React useContext & useReducer - 在应用程序中需要全局状态,对使用一个和多个 reducer 感到困惑

[英]React useContext & useReducer - Need global state in app, confused about using one vs multiple reducers

I need to share pieces of information across my app, like user details, avatar, and in-app alerts.我需要在我的应用程序中共享信息片段,例如用户详细信息、头像和应用程序内提醒。 I'm concerned I might not be using useReducer and useContext the right way since I'm just subscribing everything to this one reducer and using it as a giant global state-setting function.我担心我可能没有以正确的方式使用 useReducer 和 useContext,因为我只是将所有内容订阅到这个 reducer 并将其用作一个巨大的全局状态设置函数。 Should I be approaching this differently?我应该以不同的方式处理这个问题吗?

const initialState : IStore = { isLoading : true, isSignedIn : false, newUser : false, hero : null, alerts : [] };
const store = createContext<IStore>(initialState);
const { Provider } = store;

const StateProvider : React.FC = ( { children } ) => {
  const [state, dispatch] = useReducer((state : IStore, action : IAction) => {

    switch(action.type) {
      case 'TOGGLE LOADING': {
        const { isLoading } = action.payload;
        if(typeof isLoading === 'undefined'){
          return Object.assign({}, state, { isLoading : !state.isLoading });
        }
        return Object.assign({}, state, { isLoading });
      }
      case 'SET EXISTING USER INIT DATA': {
        const { user, hero, gameItems, latestBattle, isSignedIn } = action.payload;
        return { ...state, ...{ user, hero, gameItems, latestBattle, isSignedIn } };
      }
      case 'SET ISSIGNEDIN': {
        const { isSignedIn } = action.payload;
        return { ...state, isSignedIn };
      }
      case 'SET NEW USER': {
        const { newUser } = action.payload;
        return { ...state, newUser };
      }
      case 'SET HERO': {
        const { hero } = action.payload;
        return { ...state, hero };
      }
      case 'SET USER': {
        const { user } = action.payload;
        return { ...state, user };
      }
      case 'SET ALERTS': {
        const { alerts }  = action.payload;
        return { ...state, alerts : [...alerts] };
      }
      case 'REMOVE ALERTS': {
        const { indiciesForRemoval } = action.payload;
        return { ...state, alerts : 
          state.alerts.filter((alert) => {
            return !indiciesForRemoval.includes(alert.index);
          })
        };
      }
      default:
        throw new Error('In Store default, should not happen.');
    };
  }, initialState);

  return (
    <Provider value={{ state, dispatch }}>
      {children}
    </Provider>
  );
};

It's more of a question of code quality:更多的是代码质量的问题:

  • Does it make sense to store all this data and the related actions in this single reducer?将所有这些数据和相关操作存储在这个单一的减速器中是否有意义?
  • Would be more logical and/or maintainable to split the reducer into several reducers instead?将减速器拆分为多个减速器会更合乎逻辑和/或可维护吗?
  • If I move part of this reducer into a separate reducer, could it be reused elsewhere?如果我将这个减速器的一部分移动到一个单独的减速器中,它可以在其他地方重复使用吗?

If you're only using a bit of state and only a handful of actions, a single reducer is just fine.如果你只使用一点状态和少量动作,一个减速器就可以了。 One thing you have to look out for is re-render triggering: whenever your reducer's state gets updated, every component making use of that reducer will have to be re-rendered.您必须注意的一件事是重新渲染触发:每当您的减速器的状态更新时,每个使用该减速器的组件都必须重新渲染。 For small states, not a problem, but if you eg have a lot of complex components needing state.fieldA and a lot of complex components needing state.fieldB , then it might be worth splitting.对于小状态,这不是问题,但是如果你有很多需要state.fieldA的复杂组件和很多需要state.fieldB的复杂组件,那么它可能值得拆分。 Otherwise updating fieldA would also trigger a re-render for all the components that are only interested in fieldB .否则更新fieldA也会触发所有只对fieldB感兴趣的组件的重新渲染。 Although certain optimizations could be made to partially counteract that.尽管可以进行某些优化以部分抵消这种情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用带有自定义钩子的 useContext 与 useContext + useReducer - using useContext with custom hooks vs useContext + useReducer 反应 useContext useReducer state 挂钩错误 - React useContext useReducer state Hooks Error React useReducer:如何组合多个减速器? - React useReducer: How to combine multiple reducers? 使用 React useContext 和 useReducer 时出现打字稿错误 - Typescript error when using React useContext and useReducer 在反应中将 useReducer 与 useContext 一起使用时未定义“调度” - 'dispatch' is not defined when using useReducer with useContext in react 未捕获的类型错误:将 useReducer 和 useContext 用于全局存储 React js 时,对象不可迭代 - Uncaught TypeError: Object is not iterable when using useReducer with useContext for global store React js 将 useContext/useReducer 与 useQuery 一起使用时,没有数据传递到 state - no data is passed into state when using useContext/useReducer together with useQuery 错误:在 React useContext 和 useReducer 中未定义 - ERROR: undefined in React useContext and useReducer 在 React 中使用 useContext 和 useReducer 创建新的键值对 - Create new key-value pairs using useContext and useReducer in React 在 React 中使用 useContext 使 state 在整个应用程序中可用 - Making a state available throughout the app using useContext in React
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM