I am currently seeing this error with my current setup.
Type '({ team: string | null; } | { team: string | null; } | { ...; } | { ...; } | { ...; } | Dispatch<...>)[]' is missing the following properties from type 'State': teamts(2739) index.d.ts(290, 9): The expected type comes from property 'value' which is declared here on type 'IntrinsicAttributes & ProviderProps'
My code is below, if any more detail is required let me know.
actions.ts
export const setTeam = (team: string | null) => ({
type: 'SET_TEAM',
team,
});
reducer.ts
export const initialState = {
team: null,
};
type State = {
team: string | null;
};
export const GlobalContext = React.createContext<State | null>(null);
export const reducer = (state: State, action: any) => {
switch (action.type) {
case actionTypes.SET_TEAM:
const team = action.team;
return {
...state,
team,
};
default:
return state;
}
};
App.tsx
const App = () => {
const [state, dispatch] = React.useReducer(reducer, initialState);
return (
// error with state and dispatch here
<GlobalContext.Provider value={[state, dispatch]}>
...App code
</GlobalContext.Provider>
)
}
Team.tsx
import { GlobalContext } from './reducers';
import { setTeam } from './actions';
const Team = () => {
const [, dispatch] = React.useContext(GlobalContext);
return <span onClick={() => dispatch(setTeam('LFC'))}>LFC</span>
}
Conclusion. The useReducer() hook in React lets you separate the state management from the rendering logic of the component. const [state, dispatch] = useReducer(reducer, initialState) accepts 2 argument: the reducer function and the initial state.
The useReducer hook is usually recommended when the state becomes complex, with state values depending on each other or when the next state depends on the previous one. However, many times you can simply bundle your separate useState statements into one object and continue to use useState .
React useReducer doesn't support async actions natively. Unlike Redux, there's no middleware interface, but hooks are composable. This is a tiny library to extend useReducer's dispatch so that dispatching async actions invoke async functions.
Can useReducer replace Redux? The useReducer hook should be used in components that have complex logic behind it. It shows as the main confusion with the Redux library, because developers tend to think that useReducer could replace the state manager library. But in fact, its use should be restricted to components.
If you want to pass the state and the dispatch through context you have to type it on the context, you can go with just this line but if you want type safety read further
const GlobalContext = React.createContext<[State, React.Dispatch<any>]>([
{ team: null },
() => {},
])
You can change the <any>
inside React.Dispatch
to your action types if you want type safety for actions, you would also need to type the action inside the reducer
enum TeamTypes {
SET_TEAM = 'SET_TEAM',
REMOVE_TEAM = 'REMOVE_TEAM',
}
type State = {
team: string | null
}
export const initialState: State = {
team: null,
}
type SetTeamAction = {
type: typeof TeamTypes.SET_TEAM
team: string
}
type RemoveTeamAction = {
type: typeof TeamTypes.REMOVE_TEAM
}
type TeamActionTypes = SetTeamAction | RemoveTeamAction
export const setTeam = (team: string): TeamActionTypes => ({
type: TeamTypes.SET_TEAM,
team,
})
export const GlobalContext = React.createContext<
[State, React.Dispatch<TeamActionTypes>]
>([{ team: null }, () => {}])
export const reducer = (state: State, action: TeamActionTypes): State => {
switch (action.type) {
case TeamTypes.SET_TEAM:
const { team } = action
return {
...state,
team,
}
default:
return state
}
}
const App = () => {
const [state, dispatch] = React.useReducer(reducer, initialState)
return (
<GlobalContext.Provider value={[state, dispatch]}></GlobalContext.Provider>
)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With