I had the following code to define a typed selector with Redux in TypeScript:
import { useSelector, TypedUseSelectorHook } from 'react-redux';
export interface RootState {
user: {
account: string;
}
};
export const useTypedSelector: TypedUseSelectorHook<RootState> = useSelector;
Now I see that TypedUseSelectorHook
is deprecated and should be replaced by createSelectorHook<State, Action>()
.
Not sure how to change it and if Action
must be there as well. Any suggestion?
The useSelector
hook has two generic variables: the type of the entire state (TState
) and the type of the value which you are selecting (TSelected
). We want to make a bound hook where TState
is known, but TSelected
varies depending on the selector argument that we call the hook with.
TypedUseSelectorHook
is basically just a typescript override. The value of your useTypedSelector
is just useSelector
.
createSelectorHook
is a little bit different because it's a factory function which returns a useSelector
hook. It takes a context as an optional argument (docs link) and it has a second generic variable for Action
because that context
depends on the action type. Your selector hook doesn't depend on the action type so you don't need to worry about it. Luckily the Action
variable is optional and defaults to AnyAction
. You just need to set the generic for the state:
export const useTypedSelector = createSelectorHook<RootState>();
The type for useTypedSelector
is what we expect, which is a hook with only one generic describing the selected value:
const useTypedSelector: <Selected extends unknown>(
selector: (state: RootState) => Selected,
equalityFn?: ((previous: Selected, next: Selected) => boolean) | undefined
) => Selected
Playground Link
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With