I am declaring useMemo onload of page for pagination. It is working fine. But when I tried to declare inside a response of service call I am getting this error "React Hook "useMemo" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function". Please find the code below just for reference.
Test.js
import React, { useState, useEffect,useMemo,useRef } from 'react';
const Test = React.forwardRef((props, ref) => {
const [currentPage, setCurrentPage] = useState(1);
const [posts, setPosts] = useState([]);
const currentTableData = useMemo(() => { // working fine
const firstPageIndex = (currentPage - 1) * PageSize;
const lastPageIndex = firstPageIndex + PageSize;
const getData = JSON.parse(sessionStorage.getItem("tableData"));
//console.log(getData)
return getData.slice(firstPageIndex, lastPageIndex);
}, [currentPage]);
const formikfilter = useFormik({
initialValues: {
month: '',
year: '',
amount: ''
},
// validate: validatefData,
onSubmit: values => {
// resetForm();
var config = { "Access-Control-Allow-Origin": "*" }
fetchData(values.year, config, (res) => {
setPosts(res.data.items);
const currentTableData = useMemo(() => { // getting errror
const firstPageIndex = (currentPage - 1) * PageSize;
const lastPageIndex = firstPageIndex + PageSize;
const getData = JSON.parse(sessionStorage.getItem("tableData"));
//console.log(getData)
return getData.slice(firstPageIndex, lastPageIndex);
}, [currentPage]);
}, (err) => {
//error
});
}
});
})
3
Answers
I believe the error message is clear – you are calling the
useMemo
hook inside a function, not inside a React component or a custom hook. If you really want to use this hook, you would have to move it out, to the component body, but it would require significant code structure changes to be able to access thevalues
property, e.g. using theformik context
.Anyways, the usage of
useMemo
here does not make much sense, because it is meant to avoid unnecessary, heavy recalculations betweenre-renders
, but in your particular case, the recalculations will be done only on theonSubmit
event, not between there-renders
. Any visible performance downsides will not occur.You’re encountering the error due to the fact that you’re attempting to use the useMemo hook inside a callback function (onSubmit callback of formikfilter). React hooks, including useMemo, are meant to be used directly within the functional component’s body or within custom hook functions, but not within nested functions or callbacks.
useMemo cannot be called directly inside the onSubmit callback. Instead, you can calculate the currentTableData outside of the callback, preferably inside the main body of the functional component, using a regular variable or a separate function.
You can try adjusting the code as below;
With the suggested code the currentTableData variable is calculated once within the component’s main body using useMemo. Since it depends on currentPage, it will automatically update when currentPage changes.
Additionally, you don’t need to manually recalculate currentTableData inside the onSubmit callback. React’s reactivity system will handle that for you when setPosts is called.
React hooks cannot have local scope in a component, they need to included in global scope. You are declaring it a function hence it won’t be available outside the function and ultimately killing the purpose of using it. What you can do is declare the memo on global scope and store the data in a state, use currentPage state in your memo dependency then change the state in callback function as you did in your function. Also, I can’t seem to understand why would you want to call memo in your callback function, if its cause you want to trigger it when you can a response then you may wanna add Posts in your dependency array of memo.