我正在做一个关于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>
);
}