简体   繁体   中英

Setting up React / Redux typescript for hooks

I've been looking at different resources online trying to find a working solution for what I have and so far I think I'm kinda botching my typescript integration. I'd love to have some help in properly setting up my types for my hook.

I have a useUser() hook that dispatches actions to my reducer and also returns selectors back from my store. I've made some progress, but I'm starting to get in over my head a little bit.

the hook: useUser.ts

  • I'm not sure what I can place as the return for this hook. I tried placing useUserActionTypes but I don't think that makes any difference, especially since I'm not returning anything really beyond either getting an object ( userData ), or a number ( totalPoints , totalWords ) from the store.
  • I dont think I should be "returning" my dispatches, but it made typescript less upset
  • I can also just type in something like 'Dog' instead of FETCH_USER into my dispatch's type for example. Probably doesn't matter, but I think there should be a safeguard in there, right?
  • Pretty stumped with how to actually fix that error in the destructured return. I have a type called User that represents an object that my store will have for user, but ... that made no difference.
import { useSelector, useDispatch } from 'react-redux';
import axios from 'axios';
import { User } from '../reducers/user';

export const FETCH_USER = 'FETCH_USER';
export const UPDATE_ERRORS = 'UPDATE_ERRORS';
export const INCREMENT_POINTS = 'INCREMENT_POINTS';
export const INCREMENT_WORDS = 'INCREMENT_WORDS';

type Error = {
  code: number;
  message: string;
};

type FetchUserAction = {
  type: typeof FETCH_USER;
  payload: User;
};

type UpdateErrorsAction = {
  type: typeof UPDATE_ERRORS;
  payload: Error[];
};

type IncrementPointsAction = {
  type: typeof INCREMENT_POINTS;
  payload: number;
};

type IncrementWordsActions = {
  type: typeof INCREMENT_WORDS;
};

// ? Typescript is able to infer the correct type in the Union Type below
export type useUserActionTypes =
  | FetchUserAction
  | UpdateErrorsAction
  | IncrementPointsAction
  | IncrementWordsActions;

export type ReduxStore = {
  alert: any;
  user: User;
};

const useUser = (): useUserActionTypes => {
  const userData: User = useSelector((state: ReduxStore) => state.user);
  const totalPoints: number = useSelector(
    (state: ReduxStore) => state.user.points
  );
  const totalWords: number = useSelector(
    (state: ReduxStore) => state.user.words
  );
  const dispatch = useDispatch();
  const fetchUser = async (): Promise<FetchUserAction | UpdateErrorsAction> => {
    try {
      const response = await axios.get(
        'http://localhost:5000/api/v1/users/WhpHq4qWFdzlhlx2ztqD'
      );
      const user = response.data;
      return dispatch({
        type: FETCH_USER,
        payload: user,
      });
    } catch (error) {
      return dispatch({
        type: UPDATE_ERRORS,
        payload: [
          {
            code: 500,
            message: error.message,
          },
        ],
      });
    }
  };
  const incrementPoints = (amount: number): useUserActionTypes => {
    return dispatch({
      type: INCREMENT_POINTS,
      payload: amount,
    });
  };
  const incrementWords = (): useUserActionTypes => {
    return dispatch({
      type: INCREMENT_WORDS,
    });
  };
  return {
    userData,
    totalPoints,
    totalWords,
    fetchUser,
    incrementPoints,
    incrementWords,
  };
};

export default useUser;

在此处输入图片说明


On a page where I am trying to use the selectors:

  • I thought these were covered in my hook, I have types assigned to these constants.
  • fetchUser() returns a type of 'any' ... same issue as above perhaps?

在此处输入图片说明

在此处输入图片说明

Thank you for any help, It's definitely fun trying to get this all properly hooked up with typescript but I am a bit lost currently.

The problem is that you incorrectly typed useUser , the correct return type according to your code would be:

{
    userData: User;
    totalPoints: number;
    totalWords: number;
    fetchUser(): Promise<FetchUserAction | UpdateErrorsAction>;
    incrementPoints(amount: number): useUserActionTypes;
    incrementWords(): useUserActionTypes;
}

Playground

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM