'How to call a function inside a callback function
I am having a callback function that triggers handleCartOpen() function. But when the function is triggered I get an error showing 'setDrawerView and openDrawer is not a function
I am having a callback function that triggers handleCartOpen() function. But when the function is triggered I get an error showing 'setDrawerView and openDrawer is not a function
const { openDrawer, setDrawerView } = useUI();
function handleCartOpen() {
setDrawerView('CART_SIDEBAR');
return openDrawer();
}
const openCart = useCallback(() => {
alanInstance.playText("Opening cart")
handleCartOpen()
}, [alanInstance, handleCartOpen])
useUI Code
const initialState = {
isAuthorized: getToken() ? true : false,
displaySidebar: false,
displayFilter: false,
displayCart: false,
displaySearch: false,
displayMobileSearch: false,
displayDrawer: false,
drawerView: null,
toastText: '',
isStickyheader: false,
data: null,
};
type Action =
type: 'OPEN_SIDEBAR';
}
| {
type: 'CLOSE_SIDEBAR';
}
| {
type: 'OPEN_CART';
}
| {
type: 'CLOSE_CART';
}
| {
type: 'OPEN_DRAWER';
data: null;
}
| {
type: 'CLOSE_DRAWER';
}
| {
type: 'SET_DRAWER_VIEW';
view: DRAWER_VIEWS;
};
type DRAWER_VIEWS = 'CART_SIDEBAR' | 'MOBILE_MENU' | 'ORDER_DETAILS';
export const UIContext = React.createContext<State | any>(initialState);
UIContext.displayName = 'UIContext';
function uiReducer(state: State, action: Action) {
switch (action.type) {
case 'OPEN_SIDEBAR': {
return {
...state,
displaySidebar: true,
};
}
case 'CLOSE_SIDEBAR': {
return {
...state,
displaySidebar: false,
drawerView: null,
};
}
case 'OPEN_SHOP': {
return {
...state,
displayShop: true,
};
}
case 'OPEN_CART': {
return {
...state,
displayCart: true,
};
}
case 'CLOSE_CART': {
return {
...state,
displayCart: false,
};
}
case 'OPEN_DRAWER': {
return {
...state,
displayDrawer: true,
displaySidebar: false,
data: action.data,
};
}
case 'CLOSE_DRAWER': {
return {
...state,
displayDrawer: false,
};
}
case 'SET_DRAWER_VIEW': {
return {
...state,
drawerView: action.view,
};
}
}
}
export const UIProvider: React.FC = (props) => {
const [state, dispatch] = React.useReducer(uiReducer, initialState);
const openSidebar = () => dispatch({ type: 'OPEN_SIDEBAR' });
const closeSidebar = () => dispatch({ type: 'CLOSE_SIDEBAR' });
const toggleSidebar = () =>
state.displaySidebar
? dispatch({ type: 'CLOSE_SIDEBAR' })
: dispatch({ type: 'OPEN_SIDEBAR' });
const closeSidebarIfPresent = () =>
state.displaySidebar && dispatch({ type: 'CLOSE_CART' });
const openCart = () => dispatch({ type: 'OPEN_CART' });
const closeCart = () => dispatch({ type: 'CLOSE_CART' });
const toggleCart = () =>
state.displaySidebar
? dispatch({ type: 'CLOSE_CART' })
: dispatch({ type: 'OPEN_CART' });
const closeCartIfPresent = () =>
state.displaySidebar && dispatch({ type: 'CLOSE_CART' });
const toggleMobileSearch = () =>
state.displayMobileSearch
? dispatch({ type: 'CLOSE_MOBILE_SEARCH' })
: dispatch({ type: 'OPEN_MOBILE_SEARCH' });
const openDrawer = (data?: any) => dispatch({ type: 'OPEN_DRAWER', data });
const closeDrawer = () => dispatch({ type: 'CLOSE_DRAWER' });
const setDrawerView = (view: DRAWER_VIEWS) =>
dispatch({ type: 'SET_DRAWER_VIEW', view });
const enableStickyHeader = () => dispatch({ type: 'ENABLE_STICKY_HEADER' });
const disableStickyHeader = () => dispatch({ type: 'DISABLE_STICKY_HEADER' });
const value = React.useMemo(
() => ({
...state,
openSidebar,
closeSidebar,
openCart,
closeCart,
toggleCart,
openDrawer,
closeDrawer,
setDrawerView,
enableStickyHeader,
disableStickyHeader,
}),
[state]
);
return <UIContext.Provider value={value} {...props} />;
};
export const useUI = () => {
const context = React.useContext(UIContext);
if (context === undefined) {
throw new Error(`useUI must be used within a UIProvider`);
}
return context;
};
export const ManagedUIContext: React.FC = ({ children }) => (
<CartProvider>
<UIProvider>
<ModalProvider>{children}</ModalProvider>
</UIProvider>
</CartProvider>
);
I cut out some code that are not important to this question to make the code in useUI short
Solution 1:[1]
openDrawer and setDrawerView should be:
const openDrawer = (data?: any) => {
dispatch({ type: 'OPEN_DRAWER', data })
}
const setDrawerView = (view: DRAWER_VIEWS) => {
dispatch({ type: 'SET_DRAWER_VIEW', view })
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Lee |
