I'm using the useSelector(state => state.SLICE_NAME)
hook from React-Redux however I'm having difficulty defining the state
parameter. It is set by default as unknown
so I get an error when I try to return state.SLICE_NAME
(Error: Object is of type 'unknown'
).
How do I define the state
type without having to manually create a separate state type and adding in every new state definition as they're created?
I've tried defining state as typeof store
however that doesn't work.
Some code to help explain:
// navDrawer.ts import { createSlice } from "redux-starter-kit"; // navDrawer initial state export interface NavDrawerInitialState { open: boolean; } const navDrawerInitialState: NavDrawerInitialState = { open: false }; // Create state slice const { actions, reducer } = createSlice({ slice: "navDrawer", initialState: navDrawerInitialState, reducers: { open: (state: NavDrawerInitialState) => { state.open = true; }, close: (state: NavDrawerInitialState) => { state.open = false; } } }); export const navDrawerActions = actions; export default reducer;
// reducers.ts import navDrawer from "./navDrawer"; const reducers = { navDrawer }; export default reducers;
// store.ts import { configureStore } from "redux-starter-kit"; import reducer from "./reducers"; const store = configureStore({ reducer }); export default store;
// Page.tsx import React, { FC } from "react"; import { Provider } from "react-redux"; import store from "./store"; import ChildComponent from "./ChildComponent"; const StateProvider: FC = () => { return <Provider store={store}><ChildComponent /></Provider>; }; export default StateProvider;
// ChildComponent.tsx import React, { FC } from "react"; import { useSelector } from "react-redux"; const ChildComponent: FC = () => { const navDrawerState = useSelector(state => state.navDrawer); // ERROR OCCURS HERE. "state" is defined as 'unknown' so "state.navDrawer" throws an error. return <div>Text</div> }
Edit: I noticed that the type definition for configureStore()
contains the state as the first generic type. See screenshot below. If I can get the first generic value from EnhancedStore
then I'll be able to use that to define state. Is there any way I can do this in Typescript?
Use the React Redux Hooks API The hooks API is much simpler to use with TypeScript, as useSelector is a simple hook that takes a selector function, and the return type is easily inferred from the type of the state argument.
As of React-Redux v8, React-Redux is fully written in TypeScript, and the types are included in the published package. The types also export some helpers to make it easier to write typesafe interfaces between your Redux store and your React components.
useSelector is a function that takes the current state as an argument and returns whatever data you want from it and it allows you to store the return values inside a variable within the scope of you functional components instead of passing down as props.
This might not be the answer but I use it like so:
const isLoggedIn = useSelector<IRootState, boolean>(state => state.user.loggedIn);
EDIT: Or use Peter's answer which is shorter/cleaner
const isLoggedIn = useSelector((state: IRootState) => state.user.loggedIn);
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