仅在第一次渲染时未处理的拒绝 - React Native

Unhandled rejection on only first render - React Native

我正在尝试构建一个使用 react-native-contacts 导入联系人并将其显示在列表中的应用程序。

我的问题是我只在第一次渲染时收到未处理的承诺拒绝。这是我的组件代码,当我登录到控制台时发生错误:

function ContactsList() {
  const [contacts, setContacts] = useState({});

  // I think this function is fine, but including it for context because it might not be
  function sortData(data) {
    const dataSorted = {
      'A': [],
      'B': [],
      'C': [],
      \etc...
    };
    data.sort((a, b) => (a['name'] > b['name']) ? 1 : -1);
    for (let x in data) {
      const first = data[x]['name'][0];
      var letters = /^[A-Za-z]+$/;
      if (first.match(letters)) {
        dataSorted[first].push(data[x]);
      } else {
        dataSorted['#'].push(data[x]);
      }
    }
    setContacts(dataSorted);
  }

  useEffect(() => {
    (async () => {
      const { status } = await Contacts.requestPermissionsAsync();
      console.log('permission ' + status);
      if (status === 'granted') {
        const { data } = await Contacts.getContactsAsync().catch((error) => {console.error(error)});
        if (data.length > 0) {
          sortData(await data);
          console.log(contacts['A'][0]); // THIS IS THE LINE THAT THROWS AN ERROR
        }
      } else {
        Alert.alert(
          "Contacts Permission",
          "Sorry, we can't load your contacts because permission was not granted.",
          [{ text: "OK", onPress: () => console.log("OK Pressed") }],
          { cancelable: false }
        );
      }
    })();
  }, []);

  return (
    <View>
      <Text> These are contacts: </Text>
      {contacts['A'] && // I'm using && to stop it from rendering the list before the data gotten
      <View/> // I'll add my section list here
      }
    </View>
  );
}

当我重新加载我的应用程序时,出现此错误:

[Unhandled promise rejection: TypeError: undefined is not an object (evaluating 'contacts['A'][0]')]

我认为如果数据为空,“if (data.length > 0)”部分会阻止它尝试,如本文档所示:https://docs.expo.io/versions/latest/sdk/contacts/

如果我进行热重载,它工作正常并且我没有收到任何警告。未处理的承诺拒绝只发生在第一次渲染时。

我已经阅读了更多示例并解决了类似问题,但我仍然找不到我遗漏的内容。我是本地人的新手,所以我们将不胜感激。我当然可能误解了一些显而易见的事情。谢谢!

问题是当你这样做时

setContacts(dataSorted)

在该州不会立即可用 - 它的工作方式与 setState 那样

Think of setState() as a request rather than an immediate command to update the component. For better perceived performance, React may delay it, and then update several components in a single pass. React does not guarantee that the state changes are applied immediately.

https://reactjs.org/docs/react-component.html#setstate

您可以做的只是 return dataSorted 然后记录状态:

function sortData(data) {
    // ...
    setContacts(dataSorted);
    return dataSorted;
}

// ......
if (data.length > 0) {
    const nextContacts = sortData(await data);
    console.log(nextContacts['A'][0]); 
}