I was using a free React template which was implemented with Context+Reducer and soon, after adding complexity, I ran accross the classic re-render caveat of useContext API. Is it possible to change my Context interface to one of Redux, since I don't want to re-render everything each time a single action is dispatched. I am currently using React v17.0.2
import { createContext, useContext, useReducer, useMemo } from "react";
// prop-types is a library for typechecking of props
import PropTypes from "prop-types";
//React main context
const MaterialUI = createContext();
// Setting custom name for the context which is visible on react dev tools
MaterialUI.displayName = "MaterialUIContext";
//React reducer
function reducer(state, action) {
switch (action.type) {
case "MINI_SIDENAV": {
return { ...state, miniSidenav: action.value };
}
case "RESET_IDS": {
return { ...state, chartIds: ["Main"] };
}
case "ADD_CHART": {
return { ...state, chart: action.value, chartIds: [...state.chartIds, action.id] };
}
case "DELETE_CHART": {
return {
...state,
chart: action.value,
chartIds: state.chartIds.filter((id) => id !== action.id),
};
}
case "FILE_DATA": {
return { ...state, fileData: action.value };
}
case "ANALYSIS_DATA": {
return { ...state, analysisData: action.value };
}
case "DATA_UPLOADED": {
return { ...state, isUploaded: action.value };
}
case "LAYOUT": {
return { ...state, layout: action.value };
}
default: {
throw new Error(`Unhandled action type: ${action.type}`);
}
}
}
// React context provider
function MaterialUIControllerProvider({ children }) {
const initialState = {
miniSidenav: false,
chart: {},
chartIds: ["Main"],
fileData: [],
analysisData: [],
isUploaded: false,
layout: "page",
darkMode: false,
};
const [controller, dispatch] = useReducer(reducer, initialState);
const value = useMemo(() => [controller, dispatch], [controller, dispatch]);
return <MaterialUI.Provider value={value}>{children}</MaterialUI.Provider>;
}
//React custom hook for using context
function useMaterialUIController() {
const context = useContext(MaterialUI);
if (!context) {
throw new Error(
"useMaterialUIController should be used inside the MaterialUIControllerProvider."
);
}
return context;
}
// Typechecking props for the MaterialUIControllerProvider
MaterialUIControllerProvider.propTypes = {
children: PropTypes.node.isRequired,
};
// Context module functions
const setMiniSidenav = (dispatch, value) => dispatch({ type: "MINI_SIDENAV", value });
const resetIds = (dispatch) => dispatch({ type: "RESET_IDS" });
const addNewChart = (dispatch, value, id) => dispatch({ type: "ADD_CHART", value, id });
const deleteChart = (dispatch, value, id) => dispatch({ type: "DELETE_CHART", value, id });
const setFileData = (dispatch, value) => dispatch({ type: "FILE_DATA", value });
const setAnalysisData = (dispatch, value) => dispatch({ type: "ANALYSIS_DATA", value });
const setIsUploaded = (dispatch, value) => dispatch({ type: "DATA_UPLOADED", value });
const setLayout = (dispatch, value) => dispatch({ type: "LAYOUT", value });
export {
MaterialUIControllerProvider,
useMaterialUIController,
setMiniSidenav,
resetIds,
addNewChart,
deleteChart,
setFileData,
setAnalysisData,
setIsUploaded,
setLayout,
};
I was trying to update fileData state and I ran across a breaking issue involving infinite re-renders, aswell as some non breaking issues regarding the rendering speed and processing! Any help is much appreciated