I am using react router v6 I am trying to change the state variable (stored in context) via dispatch function (dispatch function also passes as context)
Here is the main.tsx with context provider
const router = createBrowserRouter([
{
path: "/",
element: <Root />,
loader: filmsLoader,
children: [
{
path: "/",
element: <FilmsGrid />
}
]
}
]);
ReactDOM.createRoot(document.getElementById('root')!).render(
<CssBaseline>
<Provider>
<RouterProvider router={router} />
</Provider>
</CssBaseline>
);
This is the file with context and reducer
import React, { createContext, useContext, useReducer } from
"react";
const FilterContext = createContext('popular');
const FilterReducerContext = createContext(null);
function filterReducer({state, action}) {
console.log(action.type); // Here is undefined
switch (action) {
case "popular": {
return {
filterState: "popular"
};
}
case "release-date": {
return {
filterState: "release-date"
};
}
default: return state;
}
}
export default function Provider({ children }) {
const [filterState, dispatch] = useReducer(filterReducer,
'popular');
return (
<FilterContext.Provider value={filterState}>
<FilterReducerContext.Provider value={dispatch}>
{ children }
</FilterReducerContext.Provider>
</FilterContext.Provider>
);
}
export function useFilterContext() {
return useContext(FilterContext);
}
export function useFilterReducer() {
return useContext(FilterReducerContext);
}
Component that uses dispatch
import { Box, FormControl, InputLabel, MenuItem, Select } from "@mui/material";
import { useFilterContext, useFilterReducer } from "../../../FilterContext";
function SortType() {
const filterState = useFilterContext();
const dispatch = useFilterReducer();
const changeSortType = (event) => {
dispatch({
type: event.target.value
})
};
return (
<Box
width={'100%'}
sx={{
padding: 2
}}
>
<FormControl
fullWidth
>
<InputLabel
id={'sortType-select'}
sx={{
"&.MuiInputLabel-root": {
left: -12
}
}}
>Sort by:</InputLabel>
<Select
labelId="sortType-select"
variant="standard"
onChange={event => changeSortType(event)}
value={filterState}
>
<MenuItem value={'popular'}>Popular</MenuItem>
<MenuItem value={'release-date'}>Release date</MenuItem>
</Select>
</FormControl>
</Box>
);
}
export default SortType;
I tried change a state variable using dispatch function:
- value changed -> dispatch is called
- reducer reads action value and changes a state variable
- a state variable then passes with context and can be used as a state
I got: reducer function doesn't get action object
I got error "cannot read properties of undefined" when reducer is trying to read an action object
In this block of code, filterReducer gets arguments incorrectly, it should get it like
reducer(state, action), notreducer({state, action}).That is why action is undefined