运行 在 react-native 中使用 useEffect() 时进入无限循环

Running into an infinite loop when using useEffect() in react-native

我最近开始使用 React Native,我正在使用 Expo 构建这个移动应用程序。我正在使用 useEffect() 来调用其中的函数。我只想等待 API 的响应完全完成,然后再显示结果(在本例中为 connectionName 变量)。我将 useEffect() 函数 wallets 作为第二个参数,因为我希望每当 wallets 更改时再次获取 API,但我似乎是 运行 无限循环,即使 wallets 没有改变。非常感谢任何帮助。

export default function LinksScreen() {

       const [wallets, setWallets] = React.useState([]);
       const [count, setCount] = React.useState(0);
       const [connectionName, setConnectionName] = React.useState("loading...");

       React.useEffect(() => {
          (async () => {
             fetchConnections();
          })();
       }, [wallets]);

       async function fetchConnections() {

          const res = await fetch('https://api.streetcred.id/custodian/v1/api/' + walletID + '/connections', {
             method: 'GET',
             headers: {
                Accept: 'application/json',
             },
          });
          res.json().then(res => setWallets(res)).then(setConnectionName(wallets[0].name))
       }

       return (
          <ScrollView style={styles.container} contentContainerStyle={styles.contentContainer}>
             <OptionButton
                icon="md-school"
                label={connectionName}
                onPress={() => WebBrowser.openBrowserAsync('https://docs.expo.io')}
             />
          </ScrollView>
       );
    }

你听到一个变化,然后随着它的变化,你不停地一遍又一遍地改变它

 React.useEffect(() => {
          (async () => {
             fetchConnections();
          })();
       }, []);//remove wallets

你的 useEffect 钩子 运行s 每次 wallets 改变时,它调用 fetchConnections,它调用 setWallets,然后触发你的 useEffect 钩子,因为它改变了 wallets,等等...

将一个空的依赖项数组传递给 useEffect:

React.useEffect(() => {...}, [])

这将使它 运行 仅在挂载上。

如果您仍想在 wallets 发生变化时调用 fetchConnections,则不应通过效果挂钩来执行此操作,因为您会得到您描述的无限循环。而是在调用 setWallets 时手动调用 fetchConnections。您可以创建一个函数来为您执行此操作:

const [wallets, setWallets] = useState([]);
const setWalletsAndFetch = (wallets) => {
  setWallets(wallets);
  fetchConnections(wallets);
}