It's actually a very simple, not a complicated function. But no matter what I tried, I couldn't find why it returns an endless loop when I throw the data from getAllKeys in the state. I couldn't find out why, I created a project from scratch and tried it there. Maybe it conflicts with something I wrote before, so it was put into an endless loop again. I guess the problem is in the getAllKeys function.
import {Text, View} from 'react-native';
import React, {useState} from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
const Home = () => {
const [data, setData] = useState([]);
const getAllKeys = async () => {
let keys = [];
try {
keys = await AsyncStorage.getAllKeys();
setData(keys);
} catch (e) {
// read key error
}
};
getAllKeys();
console.log(data);
return (
<View>
<Text>hi</Text>
</View>
);
};
export default Home;
CodePudding user response:
You are getting an infinite loop because getAllKeys()
is being called again and again. The first time it is called, there is this setData(keys)
being called, which re-renders the component, because there is a state change.
When the component re-renders, getAllKeys()
is called again, so setData(keys)
is called, and it goes for ever. You would wanna use a useEffect
to solve this problem, like so:
import {Text, View} from 'react-native';
import React, {useState, useEffect} from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
const Home = () => {
const [data, setData] = useState([]);
useEffect(()=>{
const getAllKeys = async () => {
let keys = [];
try {
keys = await AsyncStorage.getAllKeys();
setData(keys);
} catch (e) {
// read key error
}
};
getAllKeys();
},[])
console.log(data);
return (
<View>
<Text>hi</Text>
</View>
);
};
export default Home;
CodePudding user response:
This AsyncStorageHooks react custom hook
import {useState} from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
const AsyncStorageHooks = (key, value, mergedValue, keys) => {
const [data, setData] = useState('');
const [error, setError] = useState('');
const storeData = async () => {
try {
if (key && value) {
const jsonValue = JSON.stringify(value);
await AsyncStorage.setItem(key, jsonValue);
setData(jsonValue);
}
} catch (e) {
setError(e);
}
};
const getData = async () => {
try {
if (key) {
const jsonValue = await AsyncStorage.getItem(key);
setData(jsonValue != null ? JSON.parse(jsonValue) : '');
}
} catch (e) {
setError(e);
}
};
const mergeData = async () => {
try {
if (key && value && mergedValue) {
const jsonValue = JSON.stringify(value);
const mergedJsonValue = JSON.stringify(mergedValue);
await AsyncStorage.setItem(key, jsonValue);
await AsyncStorage.mergeItem(key, mergedJsonValue);
}
} catch (e) {
setError(e);
}
};
const removeData = async () => {
try {
if (key) {
await AsyncStorage.removeItem(key);
}
} catch (e) {
setError(e);
}
};
const getAllKeys = async () => {
let allKeys = [];
try {
allKeys = await AsyncStorage.getAllKeys();
setData(allKeys);
} catch (e) {
setError(e);
}
};
return {
data,
storeData,
getData,
removeData,
mergeData,
getAllKeys,
getMultiple,
error,
};
};
export default AsyncStorageHooks;
this is my home component
const {data, error, getData, storeData, getAllKeys} =
useAsyncStorage('@word');
getData(); // this is works and use setData
storeData(); // this is works and use setData
getAllKeys();
console.log(data);
this works without any problems, they use the same page in the same state. It doesn't go into an infinite loop. Why does the other function enter, according to the logic you said, it should also enter an infinite loop. The only getAllKeys dosen't works in other functions without any problems.
also side note: setData(allKeys); change to setData(allKeys ''); stop to infinity loop why is that