我想从其他组件的上下文中访问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功能?
答案 0 :(得分:0)
当您传递对象作为上下文值时,每当您要使用rmail字段时,都可以执行以下操作:
const ctx = useContext(UserContext);
ctx.emailLogin(...)
以便访问emailLogin
字段。或更简单:const { emailLogin } = useContext(UserContext);
别忘了先导入UserContext
。