0

I am trying to display a product from faker js using context api and useReducer as follow

CartReducer.

import { IProduct } from "../context/Context";

export interface IState {
    products: IProduct;
    cart: [];
}

type Actions =
    | {type:"ADD_TO_CART", payload:number}| {type:"REMOVE_FROM_CART", payload:number}| {type: "CHANGE_CART_QTY", payload: number }

export const cartReducer = (state:IState, action:Actions) =>{
    switch (action.type) {
        case "ADD_TO_CART":
            console.log('ADD_TO_CART')
            break;
        default:
            return state;
    }
}

Here is my Context

import React, {useContext, useReducer } from "react";
import { faker } from '@faker-js/faker';
import { cartReducer, IState } from "../reducers/CartReducer";

export interface IProduct {
    id: string;
    name: string;
    price: string;
    image: string;
    insTock: number;
    fastdelivery: boolean;
    ratings: number;
    children: React.ReactNode;
}

const CartContext = React.createContext<IProduct | null>(null);

const Context: React.FC <IProduct> = ({ children}) => {

    const products = [...Array(20)].map(() => ({
        id: faker.datatype.uuid(),
        name: faker.commerce.productName(),
        price: faker.commerce.price(),
        image: faker.image.fashion(),
        inStock: faker.helpers.arrayElement([0, 3, 5, 6, 7]),
        fastDelivery: faker.datatype.boolean(),
        ratings: faker.helpers.arrayElement([1, 2, 3, 4, 5]),
    }));

    const initialState: IState = {
        products: products,
        cart: []
    }
    const [state, dispatch] = useReducer(cartReducer, initialState);

    return (
        <CartContext.Provider value={{state, dispatch}}>
            {children}
        </CartContext.Provider>
    )
}

export default Context;

export const CartState = () => {
    return useContext(CartContext)
}

Unfortunately, I am getting the following errors

1.

Type '{ id: string; name: string; price: string; image: string; inStock: number; fastDelivery: boolean; ratings: number; }[]' is missing the following properties from type 'IProduct': id, name, price, image, and 4 more.
  1. No overload matches this call. Overload 1 of 5, '(reducer: ReducerWithoutAction, initializerArg: any, initializer?: undefined): [any, DispatchWithoutAction]', gave the following error. Argument of type '(state: IState, action: Actions) => IState | undefined' is not assignable to parameter of type 'ReducerWithoutAction'. Overload 2 of 5, '(reducer: (state: IState, action: Actions) => IState | undefined, initialState: never, initializer?: undefined): [never, Dispatch]', gave the following error. Argument of type 'IState' is not assignable to parameter of type 'never'.

What am I doing wrong here?

The Dead Man
  • 6,258
  • 28
  • 111
  • 193

1 Answers1

1

A reducer function should be (state: State, action: Action) => State, but yours is (state: State, action: Action) => State | undefined because you break out of the switch and never return anything.

You may want return state at the end of the reducer to avoid that.


I also generally recommend always annotating the return type on reducer functions, as it helps avoid a lot of these subtle mistakes.

export const cartReducer = (state:IState, action:Actions): IState =>{
    // now you get a clear error if you make a mistake here.
}
Retsam
  • 30,909
  • 11
  • 68
  • 90