preactjs / signals

Manage state with style in every framework
https://preactjs.com/blog/introducing-signals/
MIT License
3.82k stars 95 forks source link

Is there a signals equivalent API to React's useReducer? #507

Closed ghost closed 9 months ago

ghost commented 9 months ago

React has a built-in useReducer hook that lets you update your state through actions and a reducer. This simplifies managing complex state object as can separate the state's logic in a reducer function outside of the consuming component.

So far, I haven't found anything similar (maybe a useSignalReducer hook), neither in the documentation nor codebase. Does this even exist in @preact/signals or is there any plan to implement it in the future?

XantreDev commented 9 months ago

That's it:

const createSignalReducer = <TState, TAction>(initialValue: TState, computeNext: (value: TState, action: TAction) => TState) => {
    const sig = signal(initialValue)

    return [sig, (action: TAction) => {
        sig.value = computeNext(sig.peek(), action)
    }]
}

But i don't think this should be in signals package.

const useSignalReducer = <TState, TAction>(initialValue: TState, computeNext: (value: TState, action: TAction) => TState) => 
    useState(() => createSignalReducer(initialValue, computeNext))[0]
ghost commented 9 months ago

So you're saying that I should write this code in every project I want to use signals and the reducer pattern? If so, I think it should be implemented directly in the signals package. As the reducer pattern is common enough that one might get tired of rewriting and managing the same code in every single project.

XantreDev commented 9 months ago

I think this pattern can be implemented in some third party libraries. If I understand how to create good api for this feature (it probably should be object syntax, and not getter and setter one) I will implement this feature in @preact-signals/utils

rschristian commented 9 months ago

As @XantreGodlike has shown, this is easily solvable in user code and can be packaged for redistribution (as he might do in his utils package) if copy/pasting is, for some reason, unfeasible.

Reducers are a somewhat niche need for signals and so it doesn't make sense to provide here. Any additional exports will, in all likelihood, need to be valuable and useful to most in order to land. We intentionally keep these packages lightweight, we're not looking to provide misc utilities for any and all who could need them. These are primitives, state utilities to build on top of.

XantreDev commented 6 months ago

@gabrielcoronel I've added ReducerSignal to @preact-signals/utils btw