DEV Community

Ragaeeb
Ragaeeb

Posted on

🚀 useMutableState: Tiny state management hook to easily edit deeply nested properties

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 (
    <div>
        <h3>Count: {state.level1.level2.level3.level4.count}</h3>
        <button onClick={increment}>Increment</button>
    </div>
);
Enter fullscreen mode Exit fullscreen mode

into:

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

    return (
        <div>
            <h3>Count: {state.level1.level2.level3.level4.count}</h3>
            <button onClick={() => state.level1.level2.level3.level4.count++}>Increment</button>
        </div>
    );

Enter fullscreen mode Exit fullscreen mode

đź”— See it in action: Demo
đź’» Check out the code: Repo

Bug reports are welcome! 🚀

Image description

Image description

Top comments (0)

typescript

11 Tips That Make You a Better Typescript Programmer

1 Think in {Set}

Type is an everyday concept to programmers, but it’s surprisingly difficult to define it succinctly. I find it helpful to use Set as a conceptual model instead.

#2 Understand declared type and narrowed type

One extremely powerful typescript feature is automatic type narrowing based on control flow. This means a variable has two types associated with it at any specific point of code location: a declaration type and a narrowed type.

#3 Use discriminated union instead of optional fields

...

Read the whole post now!

đź‘‹ Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay