重新渲染太多Context Api React Native

时间:2020-11-08 16:47:34

标签: javascript reactjs react-native

我正在做一个关于React Native Api的名为Context的教程。当在存储库中实现它时,它可以正常工作,但是随后我想添加另一个函数,然后出现错误:“错误:重新渲染太多。React限制了渲染数量,以防止无限循环。”

原始代码UserContex.js

                    import React, { createContext, useReducer } from 'react';

                    // actions

                    const onUserLogin = (dispatch) => async () => {
                        // we will perform some Web request here
                        const response = {
                            data: {
                                name: 'Jayanta Gogoi',
                                address: 'Mumbai, India',
                                token: '3456875sdgfjshdg34623',
                            },
                        };
                        dispatch({
                            type: 'DID_LOGIN',
                            payload: response.data,
                        });
                    };

                    // reducers to handle Dispatched Actions
                    const userReducer = (state, action) => {
                        switch (action.type) {
                            case 'DID_LOGIN':
                                return {
                                    ...state,
                                    user: action.payload,
                                };
                            default:
                                return state;
                        }
                    };

                    // Map Actions, State and Reducer for Consumer Components
                    const CreateUserContext = (reducer, actions, initialState) => {
                        const UserContext = createContext();

                        const UserProvider = ({ children }) => {
                            const [userState, dispatch] = useReducer(reducer, initialState);

                            const boundActions = {};

                            for (let key in actions) {
                                boundActions[key] = actions[key](dispatch);
                            }

                            return (
                                <UserContext.Provider value={{ userState, ...boundActions }}>
                                    {children}
                                </UserContext.Provider>
                            );
                        };

                        return { UserContext, UserProvider };
                    };

                    export const { UserProvider, UserContext } = CreateUserContext(
                        userReducer,
                        {
                            onUserLogin,
                        },
                        {
                            user: undefined,
                        }
                    );

代码在UserContex.js中添加了configureGoogleSign函数,并且出现错误: “太多的重新渲染。React限制了渲染数量以防止无限循环”

                import React, { createContext, useReducer } from 'react';

                import {
                    GoogleSignin,
                    statusCodes
                } from '@react-native-community/google-signin';
                import { WEB_CLIENT_ID } from '../utils/conf';

                // actions


                const  configureGoogleSign = (dispatch)=> {
                    const response = {
                        data: {
                            status: true
                        },
                    };
                    GoogleSignin.configure({
                        webClientId: WEB_CLIENT_ID,
                        offlineAccess: false
                    });

                    dispatch({
                        type: 'configureGoogleSign',
                        payload: response.data,
                    });
                }

                const onUserLogin = (dispatch) => async () => {
                    // we will perform some Web request here
                    const response = {
                        data: {
                            name: 'Jayanta Gogoi',
                            address: 'Mumbai, India',
                            token: '3456875sdgfjshdg34623',
                        },
                    };
                    dispatch({
                        type: 'DID_LOGIN',
                        payload: response.data,
                    });
                };

                // reducers to handle Dispatched Actions
                const userReducer = (state, action) => {
                    switch (action.type) {
                        case 'configureGoogleSign':
                            return {
                                ...state,
                                user: action.payload,
                            };
                        case 'DID_LOGIN':
                            return {
                                ...state,
                                user: action.payload,
                            };
                        default:
                            return state;
                    }
                };

                // Map Actions, State and Reducer for Consumer Components
                const CreateUserContext = (reducer, actions, initialState) => {
                    const UserContext = createContext();

                    const UserProvider = ({ children }) => {
                        const [userState, dispatch] = useReducer(reducer, initialState);

                        const boundActions = {};

                        for (let key in actions) {
                            boundActions[key] = actions[key](dispatch);
                        }

                        return (
                            <UserContext.Provider value={{ userState, ...boundActions }}>
                                {children}
                            </UserContext.Provider>
                        );
                    };

                    return { UserContext, UserProvider };
                };

                export const { UserProvider, UserContext } = CreateUserContext(
                    userReducer,
                    {
                        onUserLogin,
                        configureGoogleSign
                    },
                    {
                        user: undefined,
                    }
                );

登录组件Login.js

            import React, { useEffect, useContext } from 'react'
            import { View, Text, StyleSheet, TouchableOpacity } from 'react-native'

            import { UserContext } from '../../context/UserContext'

            import {
                GoogleSigninButton,
            } from '@react-native-community/google-signin';


            export default function Login() {

                const { userState, onUserLogin, configureGoogleSign } = useContext(UserContext);
                const { user } = userState;
                return (
                    <View>
                        {user !== undefined && <Text> User Context Output: {user.name}</Text>}
                        <TouchableOpacity
                            style={{
                                height: 50,
                                width: 220,
                                marginTop: 10,
                                marginBottom: 10,
                                backgroundColor: '#FF5733',
                                borderRadius: 30,
                                justifyContent: 'center',
                                alignItems: 'center',
                            }}
                            onPress={onUserLogin}
                        >
                            <Text style={{ color: '#FFF', fontSize: 18 }}> User Login</Text>
                        </TouchableOpacity>

                    </View>

                );


            }


            const styles = StyleSheet.create({
                container: {
                    flex: 1,
                    justifyContent: 'center',
                    alignItems: 'center'
                },
                signInButton: {
                    width: 200,
                    height: 50
                },
                status: {
                    marginVertical: 20
                },
                loggedinMessage: {
                    fontSize: 20,
                    color: 'tomato'
                },
                userInfoContainer: {
                    marginVertical: 20
                },
                profileImageContainer: {
                    marginTop: 32,
                    paddingHorizontal: 24,
                    flexDirection: 'row',
                    justifyContent: 'center'
                },
                profileImage: {
                    width: 100,
                    height: 100
                },
                displayTitle: {
                    fontSize: 22,
                    color: '#010101'
                }
            });

Home.js主要组件

                import React, { Component, useState, useEffect } from 'react'
                import { View, Text } from 'react-native'

                // import LoginButton from '../../components/LoginButton'

                import Login from '../Login/Login'
                import { UserProvider } from '../../context/UserContext'

                export default function Home() {

                    return (
                        <UserProvider>
                            <Login></Login>
                        </UserProvider>
                    );
                }

App.js

      /**
       * Sample React Native App
       * https://github.com/facebook/react-native
       *
       * @format
       * @flow strict-local
       */

      import React, { useEffect } from 'react';
      import SplashScreen from 'react-native-splash-screen'

      import Home  from './src/views/Home/Home'
      export default function App() {


        useEffect(() => {
          SplashScreen.hide()
        }, []);


        return (
          <Home></Home>
        );
      }

0 个答案:

没有答案