在 useEffect 钩子中设置状态和 AsyncStorage 会导致无限循环?

vik*_*007 5 reactjs react-native asyncstorage react-hooks

我是新手hooks,最近开始在我的 React Native 项目中使用钩子。

我正在使用AsyncStorage. 首先我使用钩子初始化初始datasetData状态useState

const [data, setData] = useState([]);
Run Code Online (Sandbox Code Playgroud)

textInput我使用两个和提交按钮将数据保存到 AsyncStorage。这是saveData函数:

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();
};
Run Code Online (Sandbox Code Playgroud)

现在,我使用useEffect从 AsyncStorage 获取数据并将其设置为data状态。我正在使用数据在屏幕上呈现文本。

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);
  }
};
Run Code Online (Sandbox Code Playgroud)

[data]在 useEffect 中使用,因为我想在每次数据更改时重新渲染我的组件,即每次我在 AsyncStorage 中保存数据时。但这会导致无限循环,因为setData会导致 useEffect 无限运行。

如果我data[]它中删除它不会循环但我在渲染中的数据落后一步。因此,每当我保存数据时,它都不会显示当前数据,而是显示前一个数据。

对我在这里做错了什么的任何解释以及我该如何解决这个问题?

谢谢。

Shu*_*tri 5

正如您已经提到的,无限循环是由于您data作为依赖项传递给useEffectuseEffect 中调用的函数并在其内部设置的事实。

这里的解决方案是在 AsyncStorage 中设置值时不使用 useEffect 而是使用 setData

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();
};
Run Code Online (Sandbox Code Playgroud)