Combining useContext with useReducer to ease my state managment, currently trying to update the fetched data, and after console logging the state before and after dispatching the action i get the difference in data (0 items vs 50 items as im fetching)
The issue is I’m using Flashlist to render data (same thing with flatlist also) and after state updates it wont render new data
import {DocumentType} from "@data/Enums";
import {DocumentListInterface} from "@data/GlobalContextInterfaces";
import {filterDuplicatesById} from "@utils/Filters";
import {JointDocument} from "@data/DocumentIntefaces";
import {DocumentListAction} from "./actions/DocumentListAction";
export function DocumentStateReducer(
state: DocumentListInterface,
action: DocumentReducerAction
): DocumentListInterface {
const field: DocumentType = action.type;
switch (action.action) {
case DocumentListAction.REFRESH_DATA:
return {
...state,
...(state[field] = {
data: action.payload.items,
page: 0,
loading: true,
}),
};
default:
throw new Error("Invalid action called");
}
}
export type DocumentReducerAction = {
type: DocumentType;
action: DocumentListAction;
payload: {
items: JointDocument[];
};
};
export default function DocumentContextProvider({
children,
}: {
children: JSX.Element[];
}) {
const [state, dispatch] = useReducer(DocumentStateReducer, initialState);
return (
<DocumentContext.Provider value={{state, dispatch}}>
{children}
</DocumentContext.Provider>
);
}
export const useDocuments = () => useContext(DocumentContext)
interface DocumentContextInterface {
state: DocumentListInterface;
dispatch(action: DocumentReducerAction): void;
}
This above it the context with the reducer with the only method im currently calling the rest are not necessary
data={Documents?.state[route.params.documentType].data}
//Example usage of data in flashlist
Example of dispatching the action in useEffect hook
const action: DocumentReducerAction = {
type: route.params.documentType,
payload: {
items: DocumentTransformerServiceProvider.getServiceProvider(
route.params.documentType
).transform(result),
},
action: DocumentListAction.REFRESH_DATA,
};
Documents?.dispatch(action);
When dispatching the data is perfectly fine
>Solution :
When you the field to the state, you spread the result of the assignment (state[field] = {), which means that you add properties of the new object (data, page and loading) to the state directly:
...(state[field] = {
data: action.payload.items,
page: 0,
loading: true,
}),
This means that Documents?.state[route.params.documentType].data is undefined, but Document?.state.data is available.
Instead, just assign them to the field as part of the new state object:
return {
...state,
[field]: {
data: action.payload.items,
page: 0,
loading: true,
},
};