Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React-Redux useSelector typescript type for state

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?

enter image description here

like image 979
Jake Avatar asked Aug 13 '19 06:08

Jake


People also ask

What is useSelector 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.

Should I use TypeScript with React Redux?

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.

What is useSelector in React Redux?

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.


Video Answer


1 Answers

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);

like image 145
alextrastero Avatar answered Oct 06 '22 13:10

alextrastero