Reputation: 21
I am new to react hooks and fairly new to typescript. I have been trying to make use of hooks, specifically the useContext
hook, to manage global state (I appreciate for this example it may be overkill, but my goal is just to be able to understand it really).
I have followed a few different examples, but none using typescript and am now getting this error:
Cannot invoke an expression whose type lacks a call signature. Type 'ContextProps' has no compatible call signatures.
I've looked at multiple other questions on here which explain the solution (something about the union on the signatures), but I just can't get my head around it in relation to my code.
This is a simplified version on my code (please excuse, as I'm still learning :) ), but I get the error on the handleOpenDrawer
function in MainPage.tsx
:
App.tsx
import React, { createContext, Dispatch, useReducer } from 'react';
import MainPage from './MainPage';
interface ContextProps {
drawerState: DrawerState;
drawerDispatch: Dispatch<DrawerActions>;
}
interface DrawerState {
open: boolean;
}
const initialDrawerPosition:DrawerState = {
open: false,
};
interface DrawerActions {
type: 'OPEN_DRAWER' | 'CLOSE_DRAWER';
}
const reducer = (state:DrawerState, action:DrawerActions) => {
switch (action.type) {
case 'OPEN_DRAWER':
return {
...state,
open: true,
};
case 'CLOSE_DRAWER':
return {
...state,
open: false,
};
default:
return state;
}
};
export const DrawerDispatch = createContext({} as ContextProps);
export default function App() {
const [ drawerState, drawerDispatch ] = useReducer(reducer, initialDrawerPosition);
const value = { drawerState, drawerDispatch };
return (
<DrawerDispatch.Provider value={value}>
<MainPage />
</DrawerDispatch.Provider>
);
}
MainPage.tsx
import { useContext } from 'react';
import { DrawerDispatch } from './App';
export default function App() {
const dispatch = useContext(DrawerDispatch);
const handleOpenDrawer = () => {
dispatch({ type: 'OPEN_DRAWER' });
};
return (
<button onClick={handleOpenDrawer}>
Click me
</button>
);
}
I'm expecting to be able to update the state.open
to true using the dispatch, but instead get the error mentioned above.
Any help would be massively appreciated!
Upvotes: 0
Views: 1267
Reputation: 21
I figured it out, so thought I better put it on here in case anyone else is having the same issue.
useContext(DrawerDispatch)
returns an object and dispatch
is one of the properties on that object, so const dispatch
needs destructuring:
const { dispatch } = useContext(DrawerDispatch)
will do it.
or better variable naming:
const context = useContext(DrawerDispatch)
and then call it like context.dispatch
instead of just dispatch
.
Upvotes: 2