I'm working on implementing TypeScript on a small codebase I've been working on and having a few troubles with the above error. I've searched for answers but none seemed to fix the actual issue I was having.
I'm getting the error:
Type 'ContextType | null' is not assignable to type 'ContextType'.
I have tried setting it to null, undefined, and object, and nothing seems to help so I'd appreciate some help with this one!
Store.txt
import { useReducer, createContext, useMemo } from "react";
import { INITIAL_DATA } from './todo/constants';
import { ContextType, ITodo, ACTIONTYPE } from './todo/models';
export const StoreContext = createContext<ContextType | null>(null)
export enum ACTIONS {
DELETE_TODO = "delete_todo",
ADD_TODO = "add_todo",
};
const reducer = (state: ITodo, action: ACTIONTYPE) => {
switch (action.type) {
case ACTIONS.DELETE_TODO:
return [...action.payload];
case ACTIONS.ADD_TODO:
return action.payload;
default:
return state;
}
};
interface Props {
children: React.ReactNode;
}
export const StoreProvider = ({ children }: Props) => {
const [state, dispatch] = useReducer(reducer, INITIAL_DATA);
const contextValue: ContextType = useMemo(() => {
return { state, dispatch };
}, [state, dispatch]);
return (
<StoreContext.Provider value={contextValue}>
{children}
</StoreContext.Provider>
);
};
Component.tsx
import { useContext } from 'react';
import { StoreContext, ACTIONS } from '../../../store';
import { ContextType } from '../../models'
export const AddTodo = () => {
const { state, dispatch }: ContextType = useContext(StoreContext);
const validateFirstStep = async () => {
return await isValid(firstStepForm);
}
const closeDrawer = () => {
onClose();
}
const handleSubmit = async () => {
const newTodoEntry = { /** todo **/ }
const newData = [...state, newTodoEntry];
dispatch({ type: ACTIONS.ADD_TODO, payload: newData });
}
return (
<div>
{ /* Something Todo happens here */ }
</div>
)
}
Models.tsx
import { ACTIONS } from '../../store';
export type ITodos = {
id: string;
todoName: string;
todoType: string;
}[];
export type ContextType = {
state: ITodos;
dispatch: React.Dispatch<ACTIONTYPE>;
}
export type ACTIONTYPE =
| { type: ACTIONS.ADD_TODO, payload: ITodos }
| { type: ACTIONS.DELETE_TODO; payload: ITodos }
CodePudding user response:
You need to provide default context value in case of there is no provider higher in the react tree;
export const StoreContext = createContext<ContextType>({todos: [], dispatch: () => {}})