reactjs 在React上设置上下文API时出现“没有重载匹配此调用”错误

wlzqhblo  于 2023-03-12  发布在  React
关注(0)|答案(1)|浏览(135)

使用上下文API设置Reducer时,我在 useReducer 函数的 initialState 参数上收到“No Overload Matches this call”错误。我认为这是因为 mainContextReducer 函数的返回类型不正确,但它确实正确。

import type { TBudgetType } from 'types/budget';
import { TTransaction } from 'types/transaction';
import { TTxFrequency } from 'types/txFrequency';
import { TTxType } from 'types/txType';
import { TTxCategory } from 'types/txCategory';

type TStateType = {
  budgets: TBudgetType[];
  loadingBudgets: boolean;
  txTypes: TTxType[];
  loadingTxTypes: boolean;
  txFrequency: TTxFrequency[];
  loadingTxFrequency: boolean;
  txCategory: TTxCategory[];
  loadingTxCategory: boolean;
  transaction: TTransaction[];
  loadingTransaction: boolean;
};

const initials: TStateType = {
  budgets: [],
  loadingBudgets: false,
  txTypes: [],
  loadingTxTypes: false,
  txFrequency: [],
  loadingTxFrequency: false,
  txCategory: [],
  loadingTxCategory: false,
  transaction: [],
  loadingTransaction: false
};

// ####################################### Types [Begin]
enum ActionsType {
  SetBudgets,
  AddBudget,
  UpdateBudget,
  SetLoadingBudget,

  // TxTypes
  SetTxTypes,
  AddTxTypes,
  UpdateTxTypes,
  SetLoadingTxTypes,

  // TTxFrequency
  SetTxFrequency,
  AddTxFrequency,
  UpdateTxFrequency,
  SetLoadingTxFrequency,

  // TTxCategory
  SetTxCategory,
  AddTxCategory,
  UpdateTxCategory,
  SetLoadingTxCategory,

  // TTransaction
  SetTransaction,
  AddTransaction,
  UpdateTransaction,
  SetLoadingTransaction,
  RemoveTransactionRow
}

// Budgets [Begin]
type SetBudgets = {
  type: ActionsType.SetBudgets;
  payload: TBudgetType[];
};

type AddBudget = {
  type: ActionsType.AddBudget;
  payload: TBudgetType;
};

type UpdateBudget = {
  type: ActionsType.UpdateBudget;
  payload: TBudgetType;
};

type SetLoadingBudget = {
  type: ActionsType.SetLoadingBudget;
  payload: boolean;
};
// Budgets [End]

// TxTypes [Begin]
type SetTxTypes = {
  type: ActionsType.SetTxTypes;
  payload: TTxType[];
};

type AddTxTypes = {
  type: ActionsType.AddTxTypes;
  payload: TTxType;
};

type UpdateTxTypes = {
  type: ActionsType.UpdateTxTypes;
  payload: TTxType;
};

type SetLoadingTxTypes = {
  type: ActionsType.SetLoadingTxTypes;
  payload: boolean;
};
// TxTypes [End]

// TxFrequency [Begin]
type SetTxFrequency = {
  type: ActionsType.SetTxFrequency;
  payload: TTxFrequency[];
};

type AddTxFrequency = {
  type: ActionsType.AddTxFrequency;
  payload: TTxFrequency;
};

type UpdateTxFrequency = {
  type: ActionsType.UpdateTxFrequency;
  payload: TTxFrequency;
};

type SetLoadingTxFrequency = {
  type: ActionsType.SetLoadingTxFrequency;
  payload: boolean;
};
// TxFrequency [End]

// TxCategory [Begin]
type SetTxCategory = {
  type: ActionsType.SetTxCategory;
  payload: TTxCategory[];
};

type AddTxCategory = {
  type: ActionsType.AddTxCategory;
  payload: TTxCategory;
};

type UpdateTxCategory = {
  type: ActionsType.UpdateTxCategory;
  payload: TTxCategory;
};

type SetLoadingTxCategory = {
  type: ActionsType.SetLoadingTxCategory;
  payload: boolean;
};
// TxCategory [End]

// Transaction [Begin]
type SetTransaction = {
  type: ActionsType.SetTransaction;
  payload: TTransaction[];
};

type AddTransaction = {
  type: ActionsType.AddTransaction;
  payload: TTransaction;
};

type UpdateTransaction = {
  type: ActionsType.UpdateTransaction;
  payload: TTransaction;
};

type SetLoadingTransaction = {
  type: ActionsType.SetLoadingTransaction;
  payload: boolean;
};

type RemoveTransactionRow = {
  type: ActionsType.RemoveTransactionRow;
  payload: number;
};
// Transaction [End]

type Actions =
  | AddBudget
  | UpdateBudget
  | SetLoadingBudget
  | SetBudgets
  | SetTxTypes
  | AddTxTypes
  | UpdateTxTypes
  | SetLoadingTxTypes
  | SetTxFrequency
  | AddTxFrequency
  | UpdateTxFrequency
  | SetLoadingTxFrequency
  | SetTxCategory
  | AddTxCategory
  | UpdateTxCategory
  | SetLoadingTxCategory
  | SetTransaction
  | AddTransaction
  | UpdateTransaction
  | SetLoadingTransaction
  | RemoveTransactionRow;
// ####################################### Types [End]

// ################ Budgets [Begin]
export const addBudgetAction = (budget: TBudgetType): AddBudget => ({
  type: ActionsType.AddBudget,
  payload: budget
});

export const setBudgetsAction = (budgets: TBudgetType[]): SetBudgets => {
  return {
    type: ActionsType.SetBudgets,
    payload: budgets
  };
};

export const updateBudgetAction = (budget: TBudgetType): UpdateBudget => ({
  type: ActionsType.UpdateBudget,
  payload: budget
});

export const setLoadingBudgetAction = (loading: boolean): SetLoadingBudget => ({
  type: ActionsType.SetLoadingBudget,
  payload: loading
});
// ################ Budgets [Begin]

// ################ TxTypes [Begin]
export const addTxTypesAction = (txType: TTxType): AddTxTypes => ({
  type: ActionsType.AddTxTypes,
  payload: txType
});

export const setTxTypesAction = (txTypes: TTxType[]): SetTxTypes => ({
  type: ActionsType.SetTxTypes,
  payload: txTypes
});

export const updateTxTypeAction = (txType: TTxType): UpdateTxTypes => ({
  type: ActionsType.UpdateTxTypes,
  payload: txType
});

export const setLoadingTxTypeAction = (loading: boolean): SetLoadingTxTypes => ({
  type: ActionsType.SetLoadingTxTypes,
  payload: loading
});
// ################ TxTypes [End]

// ################ TTxFrequency [Begin]
export const addTxFrequencyAction = (txType: TTxFrequency): AddTxFrequency => ({
  type: ActionsType.AddTxFrequency,
  payload: txType
});

export const setTxFrequencyAction = (txTypes: TTxFrequency[]): SetTxFrequency => ({
  type: ActionsType.SetTxFrequency,
  payload: txTypes
});

export const updateTxFrequencyAction = (txType: TTxFrequency): UpdateTxFrequency => ({
  type: ActionsType.UpdateTxFrequency,
  payload: txType
});

export const setLoadingTxFrequencyAction = (loading: boolean): SetLoadingTxFrequency => ({
  type: ActionsType.SetLoadingTxFrequency,
  payload: loading
});
// ################ TxFrequency [End]

// ################ TTxCategory [Begin]
export const addTxCategoryAction = (txType: TTxCategory): AddTxCategory => ({
  type: ActionsType.AddTxCategory,
  payload: txType
});

export const setTxCategoryAction = (txTypes: TTxCategory[]): SetTxCategory => ({
  type: ActionsType.SetTxCategory,
  payload: txTypes
});

export const updateTxCategoryAction = (txType: TTxCategory): UpdateTxCategory => ({
  type: ActionsType.UpdateTxCategory,
  payload: txType
});

export const setLoadingTxCategoryAction = (loading: boolean): SetLoadingTxCategory => ({
  type: ActionsType.SetLoadingTxCategory,
  payload: loading
});
// ################ TxCategory [End]

// ################ TTransaction [Begin]
export const addTransactionAction = (txType: TTransaction): AddTransaction => ({
  type: ActionsType.AddTransaction,
  payload: txType
});

export const setTransactionAction = (txTypes: TTransaction[]): SetTransaction => ({
  type: ActionsType.SetTransaction,
  payload: txTypes
});

export const updateTransactionAction = (txType: TTransaction): UpdateTransaction => ({
  type: ActionsType.UpdateTransaction,
  payload: txType
});

export const setLoadingTransactionAction = (loading: boolean): SetLoadingTransaction => ({
  type: ActionsType.SetLoadingTransaction,
  payload: loading
});

export const removeTransactionRowAction = (id: number): RemoveTransactionRow => ({
  type: ActionsType.RemoveTransactionRow,
  payload: id
});
// ################ Transaction [End]

export const MainContext = React.createContext<{ state: TStateType; dispatch: React.Dispatch<Actions> }>({
  dispatch: () => undefined,
  state: initials
});

const mainContextReducer = (action: Actions, state: TStateType = initials): TStateType => {
  const { type, payload } = action;

  switch (type) {
    // ############# Budgets [Begin]
    case ActionsType.SetBudgets:
      const budgets = payload as TBudgetType[];
      return {
        ...state,
        budgets
      };

    case ActionsType.AddBudget:
      const addData = payload as TBudgetType;

      const { id } = addData;

      let newBudgetsAdd = [...state.budgets, addData];
      if (id !== -1) {
        newBudgetsAdd = newBudgetsAdd.filter((elem) => elem.id !== -1);
      }

      // TODO - remove
      // const { id } = addData;
      // if(id === -1) {
      //   const total = state.budgets.length;
      //   addData.id = total + 1;
      // }
      console.log('ADDING BUDGET', addData);
      return {
        ...state,
        budgets: newBudgetsAdd
      };

    case ActionsType.UpdateBudget:
      const data = payload as TBudgetType;
      const newBudgets = state.budgets.map((bud) => {
        if (bud.id === data.id) {
          return data;
        }
        return { ...bud };
      });
      return {
        ...state,
        budgets: newBudgets
      };

    case ActionsType.SetLoadingBudget:
      return {
        ...state,
        loadingBudgets: payload as boolean
      };
    // ############# Budgets [End]

    // ############# TxTypes [Begin]
    case ActionsType.SetTxTypes:
      const txTypes = payload as TTxType[];
      return {
        ...state,
        txTypes
      };

    case ActionsType.AddTxTypes:
      const addDataTypes = payload as TTxType;
      return {
        ...state,
        txTypes: [...state.txTypes, addDataTypes]
      };

    case ActionsType.UpdateTxTypes:
      const dataTxType = payload as TTxType;
      const newTxTypes = state.txTypes.map((txType) => {
        if (txType.id === dataTxType.id) {
          return dataTxType;
        }
        return { ...txType };
      });
      return {
        ...state,
        txTypes: newTxTypes
      };

    case ActionsType.SetLoadingTxTypes:
      return {
        ...state,
        loadingTxTypes: payload as boolean
      };
    // ############# TxTypes [End]

    // ############# TxFrequency [Begin]
    case ActionsType.SetTxFrequency:
      const txFrequency = payload as TTxFrequency[];
      return {
        ...state,
        txFrequency
      };

    case ActionsType.AddTxFrequency:
      const addDataTxFrequency = payload as TTxFrequency;
      return {
        ...state,
        txFrequency: [...state.txFrequency, addDataTxFrequency]
      };

    case ActionsType.UpdateTxFrequency:
      const dataTxFrequency = payload as TTxFrequency;
      const newTxFrequency = state.txFrequency.map((txType) => {
        if (txType.id === dataTxFrequency.id) {
          return dataTxFrequency;
        }
        return { ...txType };
      });
      return {
        ...state,
        txFrequency: newTxFrequency
      };

    case ActionsType.SetLoadingTxFrequency:
      return {
        ...state,
        loadingTxFrequency: payload as boolean
      };
    // ############# TxFrequency [End]

    // ############# TxCategory [Begin]
    case ActionsType.SetTxCategory:
      const txCategory = payload as TTxCategory[];
      return {
        ...state,
        txCategory
      };

    case ActionsType.AddTxCategory:
      const addDataTxCategory = payload as TTxCategory;
      return {
        ...state,
        txCategory: [...state.txCategory, addDataTxCategory]
      };

    case ActionsType.UpdateTxCategory:
      const dataTxCategory = payload as TTxCategory;
      const newTxCategory = state.txCategory.map((txType) => {
        if (txType.id === dataTxCategory.id) {
          return dataTxCategory;
        }
        return { ...txType };
      });
      return {
        ...state,
        txCategory: newTxCategory
      };

    case ActionsType.SetLoadingTxCategory:
      return {
        ...state,
        loadingTxCategory: payload as boolean
      };
    // ############# TxCategory [End]

    // ############# Transaction [Begin]
    case ActionsType.SetTransaction:
      const transaction = payload as TTransaction[];
      return {
        ...state,
        transaction
      };

    case ActionsType.AddTransaction:
      const addDataTransaction = payload as TTransaction;

      const { id: idTrans } = addDataTransaction;

      let newTxAdd = [...state.transaction, addDataTransaction];
      if (idTrans !== -1) {
        newTxAdd = newTxAdd.filter((elem) => elem.id !== -1);
      }

      // TODO - remove
      // const { id: transId } = addDataTransaction;
      // if(transId === -1) {
      //   const total = state.transaction.length;
      //   addDataTransaction.id = total + 1;
      // }
      console.log('ADDING TRANSACTION', addDataTransaction);

      return {
        ...state,
        // transaction: [...state.transaction, addDataTransaction],
        transaction: newTxAdd
      };

    case ActionsType.UpdateTransaction:
      const dataTransaction = payload as TTransaction;
      const newTransaction = state.transaction.map((txType) => {
        if (txType.id === dataTransaction.id) {
          return dataTransaction;
        }
        return { ...txType };
      });
      return {
        ...state,
        transaction: newTransaction
      };

    case ActionsType.SetLoadingTransaction:
      return {
        ...state,
        loadingTransaction: payload as boolean
      };

    case ActionsType.RemoveTransactionRow:
      const filteredTransactions = state.transaction.filter((tx) => tx.id !== +payload);
      return {
        ...state,
        transaction: filteredTransactions
      };
    // ############# Transaction [End]

    default:
      return state;
  }
};

type MainProviderPropsType = {
  children: ReactNode;
  initialState?: TStateType;
};

export const MainProvider: React.FC<MainProviderPropsType> = ({ children, initialState = initials }) => {
  const [state, dispatch] = useReducer(mainContextReducer, initialState);

  return <MainContext.Provider value={{ state, dispatch }}>{children}</MainContext.Provider>;
};

MainProvider.defaultProps = {
  initialState: initials
};

我尝试使用React中的Reducer类型,但没有成功。

c3frrgcw

c3frrgcw1#

解决方案:mainContextReducer 参数的顺序不正确。以下顺序工作const mainContextReducer = (state: TStateType = initials, action: Actions): TStateType => {

相关问题