Reputation: 23
I'm new to React.js. I want to update options in my form based on some other state.I'm calling an api to fetch the new options. So this api needs to be called whenever state change happens.
const [selectedNamespace,setselectedNamespace] = useState[default];
whenever selectedNamespace changes, I need to call fetchData api.
const fetchItemData = useCallback(() => {
setError(null);
setSuccessMessage(null);
fetch(getApiPath + selectedNamespace)
.then(response => {
if (!response.ok) {
throw new Error('Something went wrong while fetching item data');
}
return response.json();
}).then(data => {
setItemData(data);
}).catch(error => {
setError(error.message);
})
}, []);
This is the useEffect function that I'm using to call this :
useEffect(() => {
if (!isEmptyString(selectedNamespace))
fetchItemData();
}, [selectedNamespace, fetchItemData])
The problem that I'm facing is that the selectedNamespace parameter that I'm accessing in my fetchItemdData is always empty. I think the state update is getting delayed because of which I'm not able to get the selectedNamespace. I'm new to useEffect and useCallback hook. Can someone pls let me know my mistake and the proper way to handle this?
Upvotes: 2
Views: 1140
Reputation: 309
useCallback is the hook that is used when we need a memorized callback. ( You could read about memoization from the following link https://en.wikipedia.org/wiki/Memoization )
Hence, useCallback will return a memoized version of the callback that only changes if one of the dependencies has changed. This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders. It works like the shouldComponentUpdate lifecycle hook.
That's the small note of useCallback. In the above example, you have shared that useCallback is not required when you require to update the state each time the value of a certain value changes.
const [selectedNamespace,setselectedNamespace] = useState[default];
useEffect(() => {
if (!isEmptyString(selectedNamespace))
fetchItemData();
}, [selectedNamespace, fetchItemData])
function fetchItemData(){
//Whatever data you want
}
function onSetValueOfNamespace(){
setselectedNamespace("abcd");
}
Hence whenever you will set the value of namespace useEffect will be called. Also, useEffect will be called once in the beginning whenever you will mount this particular component. I hope this answer will help
Upvotes: 1
Reputation: 377
I'm pretty sure, you don't need to wrap fetchItemdData inside useCallback.
The problem that I'm facing is that the selectedNamespace parameter that I'm accessing in my fetchItemdData is always empty.
const fetchItemData = useCallback(() => {
...
, []); // <--- empty dependency. This is why selectedNamespace always empty
Upvotes: 2