I have recently written a table component using hooks , and every time page loads there is an API call to backend, so meanwhile there is a loading Spinner will be shown until there is an response from the API. I'm using redux as state management, so when there is a response from API , an action is dispatched and state is updated. So the problem here is ,usually in class component we can compare prevProps and nextProps using
componentDidUpdate(prevProps){
if(this.props.someState !== prevProps.someState){
// do something
}
}
but i'm not sure how to achieve the same using Hooks. I also referred this stackoverflow question How to compare oldValues and newValues on React Hooks useEffect?
but this solution doesn't seem to be working in my case . I did try creating custom hook usePrevious and creating a ref to compare current value ,this didn't solve my issue.
Here's my part of code.
let loading = true;
let tableData = useSelector((state) => {
if (
state.common.tableDetails.data &&
state.common.tableDetails.status === true
) {
loading = false;
return state.common.tableDetails.data;
}
if (
state.common.tableDetails.data &&
state.common.tableDetails.status === false
) {
loading = true;
}
return [];
});
// table component
<Fragment>
{
loading === true ? <Spinner /> : <TableComponent tableData={tableData }/>
}
</Fragment>
So whenever the component loads, if there is any data present in redux state , that data is shown and no comparison is done for prevProps and nextProps because of which Loading spinner won't show up and after a response of newly called api state will be update and new data will be shown in Table.
UPDATE 1: Here's the code for dispatch and action and reducer
useEffect(() => {
dispatch(fetchDetails(params.someID));
}, [dispatch, params.someID]);
Action File
export const fetchDetails = (data) => (dispatch) => {
axios
.post(
`${SomeURL}/fetchAll`,
data
)
.then((res) => {
if (res.data.status) {
dispatch({
type: FETCH_DETAILS,
payload: res.data,
});
}
})
.catch((err) => console.log(err));
};
Reducer File
const initialState = {
tableDetails: {},
};
export default function (state = initialState, action) {
switch (action.type) {
case FETCH_DETAILS:
return {
...state,
tableDetails: action.payload,
};
default:
return state;
}
}