Mi caso de uso actual requiere almacenar las actualizaciones de estado más recientes en un caché. Como las actualizaciones de estado son asíncronas y puede haber muchos componentes que se actualicen en paralelo, podría ser una buena opción almacenarlos dentro del cuerpo de las funciones puras useState o useReducer.
Pero... vienen los efectos secundarios, y empieza la frustración. He intentado esperar los envíos, creando ganchos personalizados "useReducerWithCallback" y otras cosas, pero no veo la solución correcta a mi problema.
Tengo un módulo usersCache.js que me proporciona los métodos necesarios para realizar modificaciones en mi caché:
const cache = {}; export const insert = (id, data) => ... export const get = (id) => ... // and more stuffEstoy tratando de actualizar este caché cuando realizo actualizaciones de estado. Por ejemplo:
const currentUser = useContext(CurrentUserContext); ... // Note: setData is just the state setter useState hook currentUser.setData((prevData) => { const newTotalFollowing = prevData.totalFollowing + 1; usersCache.update(currentUser.data.id, { newTotalFollowing }); <---- SIDE EFFECT return { ...prevData, totalFollowing: newTotalFollowing }; });Y lo mismo en mi otro reductor de usuarios
import { usersCache } from "../../services/firebase/api/users" export default (otherUsers, action) => { switch (action.type) { case "follow-user": { const { userId, isFollowing } = action; const prevUserData = otherUsers.get(userId); const newTotalFollowers = prevUserData.totalFollowers + (isFollowing ? 1 : -1); usersCache.update(userId, { totalFollowers: newTotalFollowers }); // merge update return new Map([ ...otherUsers, [ userId, { ...prevUserData, totalFollowers: newTotalFollowers ] ] ); } ... } }Como en funciones puras, no deberíamos realizar efectos secundarios ... ¿Hay algún otro enfoque para manejar esto?
Nota: no estoy usando Redux
Puede verificar este ejemplo de trabajo completo utilizando el patrón de repositorio y los ganchos de reacción para simplificar las acciones asíncronas con los despachos de estado. Sé que no está usando redux, pero puede adaptar este ejemplo usando el enlace useReducer para conectarlo a su tienda React Context.