消耗在_app.js中实现的React.createContext()

时间:2020-11-05 22:42:50

标签: reactjs next.js

我想从其他组件的上下文中访问emailLogin

userContext.js

import React, { useEffect, useState } from 'react';
import cookie from 'js-cookie';
import {firebase} from './firebase-client';

export const UserContext = React.createContext();
const tokenName = 'firebaseToken';

const UserProvider = ({ children }) => {
  const emailLogin = async (email, password, redirectPath) => {
    await firebase
      .auth()
      .signInWithEmailAndPassword(email, password)
      .then(() => {
        console.log('User logged in.');
      })
      .catch((err) => {
        console.log(err);
      });
  };

  const onAuthStateChange = () => {
    return firebase.auth().onAuthStateChanged(async (user) => {
      if (user) {
        const token = await user.getIdToken();
        cookie.set(tokenName, token, { expires: 14 });
      } else {
        cookie.remove(tokenName);
      }
    });
  };

  useEffect(() => {
    const unsubscribe = onAuthStateChange();
    return () => {
      unsubscribe();
    };
  }, []);
    
      return <UserContext.Provider value={{ emailLogin }}>{children}</UserContext.Provider>;
    };
    
    export default UserProvider;

_app.js

import React from 'react';
import Head from 'next/head';
import App from 'next/app'
import cookies from 'next-cookies'
import UserProvider from '../lib/userContext'
import { ThemeProvider } from '@material-ui/core/styles';
import CssBaseline from '@material-ui/core/CssBaseline';
import theme from '../theme';

export default function MyApp(props) {
  const { Component, pageProps, user } = props;

  React.useEffect(() => {
    const jssStyles = document.querySelector('#jss-server-side');
    if (jssStyles) {
      jssStyles.parentElement.removeChild(jssStyles);
    }
  }, []);

  return (
    <React.Fragment>
      <Head>
        <title>My app</title>
        <meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width" />
      </Head>
      <ThemeProvider theme={theme}>
        <CssBaseline />
        <UserProvider>
          <Component {...{...pageProps, ...user}} />
        </UserProvider>
      </ThemeProvider>
    </React.Fragment>
  );
}
MyApp.getInitialProps = async (userContext) => {
  const { ctx } = userContext;
  let error;
  const appProps = await App.getInitialProps(userContext);
  const { firebaseToken } = cookies(ctx);
  if (firebaseToken) {
    try {
      const headers = {
        'Context-Type': 'application/json',
        Authorization: JSON.stringify({ token: firebaseToken }),
      };
      const dev = process.env.NODE_ENV === 'development';
      const server = dev ? 'http://localhost:3000' : 'https://firebase-app-taupe.vercel.app/';
      const result = await fetch(`${server}/api/validate`, { headers }).then((res) => res.json());
      return { ...result, ...appProps };
    } catch (e) {
      console.log(e);
    }
  }
  return { ...appProps };
};

auth.js

import { useContext } from 'react'
import Button from '@material-ui/core/Button'
import {Grid, TextField} from '@material-ui/core'
import UserContext from '../lib/userContext'


const auth = () => {
    const { emailLogin } = useContext(UserContext);
  return (
    <Grid container spacing={0} direction="column" alignItems="center" justify="center" style={{ minHeight: '100vh' }}>
      <Grid item>
        <div>
          <TextField value="diegopitt@gmail.com" label="email" /><br /><br />
          <TextField value="12345678" label="password" type="password" /><br /><br />
          <Button variant="contained" color="primary"  onClick={() => login('diegopitt@gmail.com', '12345678')}>Sign In</Button>
        </div>
      </Grid>   
    </Grid> 
  )
}

export default auth

如何从身份验证组件访问emailLogin功能?

1 个答案:

答案 0 :(得分:0)

当您传递对象作为上下文值时,每当您要使用rmail字段时,都可以执行以下操作:

const ctx = useContext(UserContext);
ctx.emailLogin(...)

以便访问emailLogin字段。或更简单:const { emailLogin } = useContext(UserContext);

别忘了先导入UserContext