import React , { createContext , useReducer , useContext } from "react" ; import { AppState } from "./App" ; import { nanoid } from "nanoid" ; import { findItemIndexById } from "./utils/findItemIndexById" ; type Action = { type : "ADD_LIST" ; payload : string ; } | { type : "ADD_TASK" ; payload : { text : string ; listId : string ; } ; } ; interface AppStateContextProps { state : AppState ; dispatch : React . Dispatch < any > ; } const AppStateContext = createContext < AppStateContextProps > ( { } as AppStateContextProps ) ; const appStateReducer = ( state , action ) : AppState => { switch ( action . type ) { case "ADD_LIST" : { return { ... state , lists : [ ... state . lists , { id : nanoid ( ) , text : action . payload , tasks : [ ] } ] } ; } case "ADD_TASK" : { const targetLaneIndex = findItemIndexById ( state . lists , action . payload . listId ) ; state . lists [ targetLaneIndex ] . tasks . push ( { id : nanoid ( ) , text : action . payload . text } ) ; return { ... state } ; } default : { return state ; } } } ; const appData = { lists : [ { id : "0" , text : "To Do" , tasks : [ { id : "c0" , text : "Generate app scaffold" } ] } , { id : "1" , text : "In Progress" , tasks : [ { id : "c2" , text : "Learn Typescript" } ] } , { id : "2" , text : "Done" , tasks : [ { id : "c3" , text : "Begin to use static typing" } ] } ] } ; export const AppStateProvider = ( { children } ) => { const [ state , dispatch ] = useReducer ( appStateReducer , appData ) ; return ( < AppStateContext . Provider value = { { state , dispatch } } > { children } < /AppStateContext.Provider>); } ; export const useAppState = ( ) => { return useContext ( AppStateContext ) ; } ;