After years of frustration with React’s immutability rules—constantly spreading state just to update a nested property—I decided enough was enough. The code was cluttered, error-prone, and hard to read. So, I built useMutableState(), a tiny React hook that leverages the Proxy pattern to make deep state updates effortless. No more spreading—just mutate directly, and React handles the rest! Turn: const [state, setState] = useState({ level1: { level2: { level3: { level4: { count: 0 } } } }, }); const increment = () => { setState((prev) => ({ ...prev, level1: { ...prev.level1, level2: { ...prev.level1.level2, level3: { ...prev.level1.level2.level3, level4: { ...prev.level1.level2.level3.level4, count: prev.level1.level2.level3.level4.count + 1, }, }, }, }, })); }; return ( Count: {state.level1.level2.level3.level4.count} Increment ); into: const state = useMutableState({ level1: { level2: { level3: { level4: { count: 0 } } } }, }); return ( Count: {state.level1.level2.level3.level4.count} state.level1.level2.level3.level4.count++}>Increment );

Feb 18, 2025 - 23:22
 0

After years of frustration with React’s immutability rules—constantly spreading state just to update a nested property—I decided enough was enough. The code was cluttered, error-prone, and hard to read.

So, I built useMutableState(), a tiny React hook that leverages the Proxy pattern to make deep state updates effortless. No more spreading—just mutate directly, and React handles the rest!

Turn:

const [state, setState] = useState({
    level1: { level2: { level3: { level4: { count: 0 } } } },
});

const increment = () => {
    setState((prev) => ({
        ...prev,
        level1: {
            ...prev.level1,
            level2: {
                ...prev.level1.level2,
                level3: {
                    ...prev.level1.level2.level3,
                    level4: {
                        ...prev.level1.level2.level3.level4,
                        count: prev.level1.level2.level3.level4.count + 1,
                    },
                },
            },
        },
    }));
};

return (
    

Count: {state.level1.level2.level3.level4.count}

);

into:

    const state = useMutableState({
        level1: { level2: { level3: { level4: { count: 0 } } } },
    });

    return (
        

Count: {state.level1.level2.level3.level4.count}

);