如何传递多个值以响应本机上下文 API
Posted
技术标签:
【中文标题】如何传递多个值以响应本机上下文 API【英文标题】:How to pass multiple values to react native context API 【发布时间】:2021-03-28 05:39:14 【问题描述】:我是反应原生概念的新手。我正在尝试将函数和参数传递给上下文 API,以便我可以在我的子组件中访问它们。我正在尝试实现基本的登录功能,该功能将根据用户登录状态显示不同的消息。当我将 SignIn 方法传递给我的子组件时,该功能起作用,但是当我将它与一些变量一起发送时,无法访问相同的函数。下面的代码和注释可以清楚地说明问题。
在下面的代码中,你可以看到我正在传递我的减速器函数和初始状态,从中我得到错误消息和签名函数<AuthenticationContext.Provider value=[authContext, initialLoginState]>
App.js
import * as React from 'react';
import NavigationContainer from '@react-navigation/native';
import BottomNavigation from './src/Navigations/BottomNavigation';
import AuthStackNavigation from './src/Navigations/AuthStackNavigation'
import useEffect, useMemo, useReducer from 'react';
import View from 'react-native-animatable';
import apiCaller from "./src/api/apiCaller";
import ActivityIndicator, Text from 'react-native';
import AuthenticationContext from './src/context/AuthenticationContext'
import Provider as VideoProvider from './src/context/videoContext'
import Context as VideoContext from './src/context/videoContext'
import AsyncStorage from '@react-native-async-storage/async-storage'
export default function App()
//Initial state values
const initialLoginState =
isLoading: true,
userName: null,
userToken: null,
errorMessage: ''
//Reducer function
const loginReducer = (prevState, action) =>
switch (action.type)
case 'LOGIN':
return
...prevState,
userToken: action.token,
userName: action.id,
isLoading: false
;
case 'LOGOUT':
return
...prevState,
userName: null,
userToken: null,
isLoading: false,
;
case 'REGISTER':
return
...prevState,
userToken: action.token,
userName: action.id,
isLoading: false,
;
case 'ERROR':
return
...prevState,
errorMessage: action.response,
isLoading: false
;
default:
return userToken: null
//Defining useReducer
const [newLoginState, dispatch] = useReducer(loginReducer, initialLoginState);
const authContext = useMemo(() => (
signIn: async (email, password) =>
try
const userData =
email: email,
password: password,
;
const response = await apiCaller.post("/login", userData);
if (response.data.code == '200')
await AsyncStorage.setItem('userToken', response.data.token)
dispatch( type: 'LOGIN', id: email, token: response.data.token )
else if (response.data.code == '404')
dispatch( type: 'ERROR', response: response.data.message )
catch (err)
console.log(err);
), []);
return (
<VideoProvider value=VideoContext>
<AuthenticationContext.Provider value=authContext, initialLoginState>
<NavigationContainer>
newLoginState.userToken == null ?
<AuthStackNavigation />
:
<BottomNavigation />
</NavigationContainer>
</AuthenticationContext.Provider>
</VideoProvider>
);
在下面的文件中,我通过
获取提供者值const signIn, initialLoginState = useContext(AuthenticationContext) 但它给了我“signIn 不是函数。(在 'signIn(email, password)' 中,'signIn' 未定义)”错误,但 signIn 方法可在以下情况下访问我只是尝试单独传递和访问 SignIn 方法。
Signinscreen.js
import React, useState from 'react'
import Ionicons, MaterialIcons from '@expo/vector-icons';
import Text, View, StyleSheet, TouchableOpacity, Platform, StatusBar from 'react-native';
import WindowHeight, WindowWidth from '../utils/PlatformDimention'
import PrimaryFormInput from "../components/PrimaryFormInput";
import PrimaryFormButton from "../components/PrimaryFormButton";
import AuthenticationContext from "../context/AuthenticationContext";
import useContext from 'react';
const UserLogin = ( navigation ) =>
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const signIn, initialLoginState = useContext(AuthenticationContext)
const loginHandle = (email, password) =>
signIn(email, password);
return (
<View style=styles.container>
<StatusBar barStyle='light-content' />
<View style=styles.header>
<View style= flex: 1, >
<TouchableOpacity onPress=() => navigation.goBack()>
<MaterialIcons style=styles.goBack name="arrow-back" size=WindowHeight / 27 />
</TouchableOpacity>
</View>
<View style= flex: 2, alignItems: 'center', justifyContent: 'center', >
<Ionicons
style= color: "#fff" name="logo-bitbucket" size=WindowHeight * 10 / 100 />
</View>
<View style= flex: 1, alignItems: 'flex-end' >
</View>
</View>
<View style=styles.footer>
<View style=styles.topFlex></View>
<View style=styles.middleFlex>
<Text style=styles.loginText>Welcome!</Text>
<Text style=styles.loginSubTextSub>Login to your existing account.</Text>
<PrimaryFormInput
inputValue=email
onChangeText=(userEmail) => setEmail(userEmail)
inputPlaceHolder='Email'
iconName="user"
keyboardType="email-address"
autoCapitalize="none"
autoCorrect=false
/>
<PrimaryFormInput
inputValue=password
onChangeText=(userPassword) => setPassword(userPassword)
inputPlaceHolder='Password'
iconName="key"
secureTextEntry=true
/>
<PrimaryFormButton
ButtonText='Login'
onPress=() => loginHandle(email, password)
/>
</View>
<View style=styles.bottomFlex></View>
</View>
</View>
)
export default UserLogin
谁能告诉我如何将方法和参数都传递给我的子组件并访问它?
【问题讨论】:
【参考方案1】:你的错误就在这里
const signIn, initialLoginState = useContext(AuthenticationContext)
因为你像这样传递上下文对象
<AuthenticationContext.Provider value=authContext, initialLoginState>
你需要像这样进行解构
const authContext : signIn , initialLoginState = useContext(AuthenticationContext)
【讨论】:
非常感谢您的快速回复。破坏后我能够轻松地传递参数,但即使我通过 reducer 函数更新 errorMessage 参数,它在我的 Singin 屏幕上也显示为空。知道可能是什么原因吗? 请忽略我上面的评论。我能够从减速器获得最新值。以上是关于如何传递多个值以响应本机上下文 API的主要内容,如果未能解决你的问题,请参考以下文章