yamalight / outstated

Simple hooks-based state management for React
107 stars 7 forks source link

Computed values in store #6

Closed filipjnc closed 5 years ago

filipjnc commented 5 years ago

How do I create computed values in store? Do I just create a const based on two other values? Is it reactive this way? Can I use useMemo() from react?

Here is an example of what I try to achieve:

import { useMemo } from 'react';
import { useLocalStorage } from '../hooks';

const roles = [
  { id: 1, name: 'Software Architect' },
  { id: 2, name: 'Software Developer' },
  { id: 3, name: 'Software Tester' },
];

export const store = () => {
  const [currentRoleId, setCurrentRoleId] = useLocalStorage('currentRole', null);
  // ################# HERE ###########################
  const currentRole = roles[currentRoleId] || null;
  // - OR -
  const currentRole = useMemo(roles[currentRoleId] || null, [currentRoleId]);
  // ###################################################

  return {
    currentRoleId,
    setCurrentRoleId,
    currentRole
  };
};
yamalight commented 5 years ago

@filipjnc how would you do that in React without outstated? It'd work exactly the same way with outstated. E.g. in this case it seems like storing currentRole in store doesn't make sense at all 🤔

filipjnc commented 5 years ago

I would do one of the above options, depending on how expensive the recomputation of the composed value is. My insecurity comes from react’s docs, where they underline that hooks should exclusively be used within functional components (is a store a functional component?)

I want to put currentRole in the store since it’s being used by many components (keep it DRY).

Danke für die Tipps, I will proceed and see if I run into issues.

yamalight commented 5 years ago

@filipjnc store is just a hook itself, so if you want to recompute currentRole on currentRoleId change, you could do something like:

const store = () => {
  const [currentRoleId, setRoleId] = useLocalStorage('currentRole', null);
  const [currentRole, setRole] = useState(null);

  const setCurrentRoleId = (roleId) => {
    setRoleId(roleId);
    setRole(roles[roleId]);
  };

  return {
    currentRoleId,
    setCurrentRoleId,
    currentRole
  };
};