In the process of tackling the issue of double hook calls in Next.js dev mode, I've encountered a challenge with server API calls that cannot handle duplicates. To address this, I opted for fix #4 outlined in the following article, where I decided to create a custom fetcher:
Now, I find myself grappling with a conflict between my reducer dispatch function and API calls, causing some confusion. The issue is illustrated in the code snippet below:
component.js
import { useImmerReducer } from 'use-immer';
import dashboardReducer from './dashboardReducer.js'
export default function MyDashboard({}) {
const [state, dispatch] = useImmerReducer(dashboardReducer,{
fetchMap: {},
tableRows: [],
}
const handleAddRow = (value) => {
dispatch({type:'addRow', data:value});
}
const getRows = () => {
dispatch({type:'getRows'});
}
return (
<>
<button onClick={()=>handleAddRow('banana')}>peel</button>
state.tableRows.map((banana) => <p>{banana}</p>);
</>
)
}
dashboardReducer.js
import {createFetch,deleteFetch} from './fetcher.js'
export function dashboardReducer(draft,action) {
switch(action.type) {
case 'getRows': {
createFetch(draft.fetcher,'api/getRows',{
/*options for an http request.*/
}).then((res) => { //HERE IS THE CHALLENGE
draft.tableRows = res.json() //desired operation, details missing.
deleteFetch(draft.fetchMap,'/api/getRows');
});
break;
}
case 'addRow': {
draft.tableRows.push(action.data);
createFetch(draft.fetcher,'/api/addRow',{
/*options for an http request.*/
}).then((res) => { //HERE IS THE CHALLENGE
deleteFetch(draft.fetchMap,'/api/getRows');
});
break;
}
}
}
fetcher.js
export function createFetch(fetchMap,url,options) {
if (!fetchMap[url]) {
fetchMap[url] = fetch(url,options).then((res) => res.json());
}
return fetchMap[url];
}
export function deleteFetch(fetchMap,url) {
delete fetchMap[url]
}
Despite potential typos in the above code excerpt, as I typed it afresh errors may exist. Currently, my concern lies at points marked '//HERE IS THE CHALLENGE', where I fear I may have backed myself into a corner. Uncertainty prevails on how to scope the then() function correctly to access the required state object. Moreover, unsure if achieving this using immer and reducer functions is feasible.
My existing solution handles mutations through the reducer and manages fetcher-related issues through useState(), creating confusing code and defeating the purpose of utilizing the reducer. With more complex function calls involved in managing a detailed state object, incorporating the custom fetcher into the reducer function would greatly enhance code manageability. Hence, the key query remains: Is there a viable method to ensure the '.then()' call acts on the accurate state so the fetchMap cleans up post-api call promise resolution within the dispatcher call?