Home > database >  I keep getting " Uncaught TypeError: dispatch is not a function" whenever I try to use dis
I keep getting " Uncaught TypeError: dispatch is not a function" whenever I try to use dis

Time:10-20

So I've been learning to use useContext and useReducer hooks with action/dispatch and whenever I try to use dipatch function from any component, it throws out "Uncaught TypeError: dispatch is not a function" error.. it's been 5 days now:/

I try to access dispatch function in the following manner inside components

// context
import { ModalContext } from "../Context/Contexts/ModalContext";
import { OPEN_IMAGE_MODAL } from "../Context/action.types";

const { dispatch } = useContext(ModalContext);

dispatch({
          type: OPEN_IMAGE_MODAL,
          payload: { isEnabled: true, imageDetails: { url: doc.url } },
});

Here are the ref files

App.js

import React from "react";

// components
import Nav from "./Components/Nav";
import ImageUploadForm from "./Components/ImageUploadForm";
import ImageGrid from "./Components/ImageGrid";

// context
import { ModalContextProvider } from "./Context/Contexts/ModalContext";

const App = () => {

  return (
    <div className="App">
      <Nav />
      <ImageUploadForm />
      <ModalContextProvider>
        <ImageGrid/>
      </ModalContextProvider>
    </div>
  );
};

export default App;

ModalContext.js (Context & Context Provider creation)

import { createContext, useReducer } from "react";

// reducer
import { modalReducer } from "../Reducers/modalReducer";

// components
import ImageModal from "../../Components/ImageModal";

//  creating and exporting context
export const ModalContext = createContext();

const initialState = { isEnabled: false, imageDetails: {} };

export const ModalContextProvider = ({ children }) => {
  //  for selected/clicked image
  const [isEnabled, imageDetails, dispatch] = useReducer(
    modalReducer,
    initialState
  );

  return (
    <ModalContext.Provider value={{ isEnabled, imageDetails, dispatch }}>
      {children}
      {isEnabled && <ImageModal />}
    </ModalContext.Provider>
  );
};

modalReducer.js (reducer fn)

import { OPEN_IMAGE_MODAL, CLOSE_IMAGE_MODAL } from "../action.types";

export const modalReducer = (state, action) => {
  switch (action.type) {
    case OPEN_IMAGE_MODAL:
      return {
        ...state,
        isEnabled: true,
        imageDetails: action.payload.imageDetails,
      };
    case CLOSE_IMAGE_MODAL:
      return { ...state, isEnabled: false, imageDetails: {} };
    default:
      return { ...state };
  }
};

CodePudding user response:

I think the useReducer hook just can return 2 arrays, the satate and the dsipatch method.

CodePudding user response:

useReducer returns an array with exactly two values. You are assuming there is some third value dispatch, which is actually undefined. And undefined is not a function.

Depending on how many values you want to passdown using context you can fix this. I like to pass only two values, one state and one dispatch.

const [state, dispatch] = useReducer(
    modalReducer,
    initialState
  );

  return (
    <ModalContext.Provider value={{ state, dispatch }}>
      {children}
      {state.isEnabled && <ImageModal />}
    </ModalContext.Provider>
  );

In children just extract how you do:

const { dispatch } = useContext(ModalContext);
  • Related