【问题标题】:How to pass multiple values to react native context API如何传递多个值以响应本机上下文 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

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

【问题讨论】:

    标签: reactjs react-native react-props react-context


    【解决方案1】:

    你的错误就在这里

    const { signIn, initialLoginState } = useContext(AuthenticationContext)
    

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

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

    你需要像这样进行解构

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

    【讨论】:

    • 非常感谢您的快速回复。破坏后我能够轻松地传递参数,但即使我通过 reducer 函数更新 errorMessage 参数,它在我的 Singin 屏幕上也显示为空。知道可能是什么原因吗?
    • 请忽略我上面的评论。我能够从减速器获得最新值。
    猜你喜欢
    • 1970-01-01
    • 2020-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多