如何传递多个值以响应本机上下文 API

How to pass multiple values to react native context API

我是 React 原生概念的新手。我正在尝试将函数和参数传递给上下文 API,以便我可以访问子组件中的那些。我正在尝试实现基本的登录功能,该功能将根据用户登录状态显示不同的消息。当我将 SignIn 方法传递给我的子组件时,该功能有效,但当我将它与某个变量一起发送时,无法访问相同的功能。下面的代码和注释可以清楚地说明问题。

在下面的代码中,您可以看到我正在传递我的 reducer 函数和初始状态,我从中获取错误消息和签名函数 <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

你们谁能告诉我如何将方法和参数传递给我的子组件并访问它吗?

你的错误就在这里

const { signIn, initialLoginState } = useContext(AuthenticationContext)

因为你像这样传递上下文对象

<AuthenticationContext.Provider value={{authContext, initialLoginState}}>

你需要像这样进行解构

const { authContext : { signIn }, initialLoginState } = useContext(AuthenticationContext)