添加字体后渲染的钩子比上一次渲染时更多

时间:2021-01-04 12:16:28

标签: javascript react-native react-hooks

我刚开始学习 React Native 代码,这是我的应用程序的验证。最初我没有加载任何字体,它一直工作得很好!添加字体后,出现这个错误,AppLoading 在加载时抛出了一个意外错误:错误:比上一次渲染时渲染了更多的钩子。

代码如下:

const FetchFonts = () => {
    return Font.loadAsync({
        'kumbhsans-bold': require('./assets/fonts/KumbhSans-Bold.ttf'),
        'kumbhsans-light': require('./assets/fonts/KumbhSans-Light.ttf'),
        'kumbhsans-regular': require('./assets/fonts/KumbhSans-Regular.ttf')
    })
};

export default function App() {
    const [fontLoaded, setFontLoaded] = useState(false);
    const [loginState, dispatch] = useReducer(loginReducer, initialLoginState);

    if (!fontLoaded) {
        return (
            <AppLoading
                startAsync={FetchFonts}
                onFinish={() => setFontLoaded(true)}
                onError={console.warn}
            />
        )
    };

    const initialLoginState = {
        isLoading: true,
        username: null,
        userToken: null,
    };

    const loginReducer = (prevState, action) => {
        switch( action.type ) {
            case 'RETRIEVE_TOKEN': 
                return {
                    ...prevState,
                    userToken: action.token,
                    isLoading: false,
                };
            case 'LOGIN': 
                return {
                    ...prevState,
                    username: action.id,
                    userToken: action.token,
                    isLoading: false,
                };
            case 'LOGOUT': 
                return {
                    ...prevState,
                    username: null,
                    userToken: null,
                    isLoading: false,
                };
            case 'REGISTER': 
                return {
                    ...prevState,
                    username: action.id,
                    userToken: action.token,
                    isLoading: false,
                };
        }
    };

    const authContext = useMemo(() => ({
        signIn: async(foundUser) => {
            const userToken = String(foundUser[0].userToken);
            const UserName = foundUser[0].username;

            try {
                await AsyncStorage.setItem('userToken', userToken)
            } catch (e) {
                console.log(e)
            };
            dispatch({type: 'LOGIN', id: UserName, token: userToken});
        },
        signOut: async() => {
            try {
                await AsyncStorage.removeItem('userToken')
            } catch (e) {
                console.log(e)
            };
            dispatch({type: 'LOGOUT'})
        },
        signUp: () => {
            setUserToken('abcd');
            setIsLoading(false);
        },
    }), []);

    useEffect(() => {
        setTimeout(async() => {
            let userToken;
            userToken = null;
            try {
                userToken = await AsyncStorage.getItem('userToken')
            } catch (e) {
                console.log(e)
            };
            dispatch({type: 'REGISTER', token: userToken})
        }, 1000);
    }, []);

    if (loginState.isLoading) {
        return(
            <View style={styles.screen}>
                <ActivityIndicator size='large'/>
            </View>
        )
    };
    
    return (
        <AuthContext.Provider value={authContext}>
            <PaperProvider>
                <NavigationContainer>
                    {
                        loginState.userToken !== null ?
                        <>
                            <Header/>
                            <RootNavigator/>
                        </>
                        : <AuthStack/>
                    }
                </NavigationContainer>
            </PaperProvider>
        </AuthContext.Provider>
    );
};

我是否遗漏了什么或我做错了什么?谢谢

1 个答案:

答案 0 :(得分:2)

如果 fontLoaded 为假,您将在调用 useReducer 之前返回。

钩子应该在每次渲染时以相同的顺序调用。