I'm new to hooks
and recently started using hooks in my React Native projects.
I'm building a simple todo app using the AsyncStorage
. First I initialize initial data
and setData
state using useState
hook:
const [data, setData] = useState([]);
There are two textInput
and submit button that I use to save data to AsyncStorage. Here is the saveData
function:
const saveData = async () => {
const arrData = [{ name: 'vikrant', phone: 123456 }]; // [{ name, phone}] from the textInput
const storedData = await AsyncStorage.getItem('user');
const storedDataParsed = JSON.parse(storedData);
let newData = [];
if (storedData === null) {
// save
await AsyncStorage.setItem('user', JSON.stringify(arrData));
} else {
newData = [...storedDataParsed, user];
await AsyncStorage.setItem('user', JSON.stringify(newData));
}
setName('');
setPhone('');
Keyboard.dismiss();
};
Now, I'm using useEffect
to get data from the AsyncStorage and setting it to the data
state. I'm using data to render the text in the screen.
useEffect(() => {
retrieveData();
}, [data]);
const retrieveData = async () => {
try {
const valueString = await AsyncStorage.getItem('user');
const value = JSON.parse(valueString);
setData(value);
} catch (error) {
console.log(error);
}
};
I'm using [data]
in useEffect since I want to re-render my component each time data changes i.e. each time I save data in AsyncStorage. But this is causing infinite loop as setData
causes useEffect to run infinitely.
If I remove data
from the []
it doesn't loop but my data in render is one step behind. So whenever I save data it doesn't show the current data but the previous one.
Any explanation of what I am doing wrong here and how can i fix this?
Thanks.
As already mentioned by you, the infinite loop is due to thefact that you pass data
as a dependency to useEffect
and also set in inside the function called in useEffect.
The solution here is to not use useEffect and instead setData whenever you are setting value in AsyncStorage
const saveData = async () => {
const arrData = [{ name: 'vikrant', phone: 123456 }]; // [{ name, phone}] from the textInput
const storedData = await AsyncStorage.getItem('user');
const storedDataParsed = JSON.parse(storedData);
let newData = [];
if (storedData === null) {
// save
await AsyncStorage.setItem('user', JSON.stringify(arrData));
} else {
newData = [...storedDataParsed, user];
await AsyncStorage.setItem('user', JSON.stringify(newData));
}
setName('');
setPhone('');
setData(newData);
Keyboard.dismiss();
};