在布局文件中使用 useState() 钩子时,React 出现无限循环

问题描述 投票:0回答:1

react-native
+
expo
+
react-native-web
中有一个项目,我需要通过布局文件显示用户名或登录链接,具体取决于用户名是否存储在存储中。

app/_layout.tsx:

import React, {useState} from 'react';
import {SafeAreaView, StyleSheet, Text, View} from 'react-native';
import {Link, Slot} from "expo-router";
import Constants from "expo-constants/src/Constants";
import storageUtil from "@/utils/storage";
import constStorage from "@/constants/Storage";

export default () => {
  // username from storage, indicate whether already login,
  const [username, setUsername] = useState<string | null>(null);
  storageUtil.getItem(constStorage.keys.username).then(v => {
    console.log('username from storage: ', v)
    if (username !== v)  // add to avoid infinite loop, TODO: improve.
      setUsername(v)
  })

  return (
    <SafeAreaView style={styles.container}>
      <View id='header' style={{flex: 1}}><Text>
        {username ?
          (<Link href="/home">{username}</Link>)
          : (<Link href="/login">Login</Link>)
        }
      </Text></View>
      <View id='main' style={{flex: 2, width: '100%', minHeight: 350, padding: 8}}>
        <Slot/>
      </View>
      <View id='footer' style={{flex: 3}}><Text>Footer</Text></View>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    paddingTop: Constants.statusBarHeight, // don't go to statusbar of phone,
    flex: 1,
    backgroundColor: '#FFF',
    position: 'relative',
    alignItems: 'center',
    justifyContent: 'center',
  },
})

如果我删除行

if (username !== v)
,在浏览器中,当我单击
username
Login
链接时,它会触发无限循环。
又名。
console.log('username from storage: ', v)
我可以看到 chrome 控制台中的这条日志行无限快速地打印出来,并且 cpu 很高。

那么,除了我添加的

if (username !== v)
之外,如何避免这种无限循环,我认为这并不优雅。

reactjs react-native react-hooks expo
1个回答
0
投票

调用

storageUtil.getItem
会导致使用
setUsername
设置用户名,导致组件重新渲染,导致调用
storageUtil.getItem
,如此反复。

为了防止这种情况,你需要使用一次性 useEffect

useEffect(() => {
  storageUtil.getItem(constStorage.keys.username).then(v => {
    setUsername(v);
  })
}, []);
© www.soinside.com 2019 - 2024. All rights reserved.