AKJ
AKJ

Reputation: 819

Using useSelector in React Function Component

I declared a state in baseReducer.ts:

import {PayloadAction} from '~common/declarations/action';

const initialState = {
  test: 'baseReducer'
};

const BaseReducer = (state = initialState, action: PayloadAction<any>): any => {
  switch(action.type) {
    default:
      return state;
  }
}

export default BaseReducer;

Then in my orderReducer:

import {PayloadAction} from '~common/declarations/action';

const initialState = {
  test: 'orderReducer'
};

const OrderReducer = (state = initialState, action: PayloadAction<any>): any => {
  switch(action.type) {
    default:
      return state;
  }
}

export default OrderReducer ;

In my rootReducer:

const RootReducer: Reducer = combineReducers({
  BaseReducer,
  OrderReducer
});

export default RootReducer;

Now in my functional component OrderPage.tsx:

export default function OrderPage() {
  const stringText: string = useSelector(state => state.test)  // HERE
  return (
    <React.Fragment>Order Page</React.Fragment>
  );
}

Here is my question:

How do I define which state to take from? Ideally I want to specify the state from OrderReducer.

When using react Classes, I could do the following:

const mapStateToProps = ({orderReducer}) => {
  return {
    test: orderReducer.test
  }
}

Edit:

I tried the following (separately of course!), but it did not work:

const reducer: string = useSelector(state => state.baseReducer);
const reducer: string = useSelector(state => state.orderReducer);

How do I achieve the same in function components?

Upvotes: 1

Views: 543

Answers (1)

Ajeet Shah
Ajeet Shah

Reputation: 19813

You need to use correct selector function in useSelector:

const stringText = useSelector(state => state.OrderReducer.test)

Or, if you write like (without using property name shorthand):

const RootReducer: Reducer = combineReducers({
  base: BaseReducer,
  order: OrderReducer
});

Then

const stringText = useSelector(state => state.order.test)

You can further avoid this error by defining RootState type:

export type RootState = ReturnType<typeof store.getState>
// ...
const stringText = useSelector((state: RootState) => state.OrderReducer.test)

Edit:

If you are getting error:

OrderReducer does not exist on DefaultRootState.

Then you should define RootState type because DefaultRootState is just export interface DefaultRootState {}.

Upvotes: 3

Related Questions