Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
6.4k views
in Technique[技术] by (71.8m points)

reactjs - the object ' const value = {}' in AuthContext.js perfectly renders its elements in Login and Signup components but shows undefined in Header.js

The elements of const value ={} object renders all their elements and their values in Login.js and Signup.js but in Header.js it shows undefined. How to render them so they don't show undefined.
AuthContext.js

import React from 'react';
import { useEffect, useState } from 'react';
import { useContext } from 'react';
import { auth } from '../firebase';
import Header from '../components/Header';

const AuthContext = React.createContext();

export function useAuth() {
   return useContext(AuthContext);
}

export const AuthProvider = ({ children }) => {
   const [currentUser, setCurrentUser] = useState();
   const [loading, setLoading] = useState(true);

function signup(email, password) {
    return auth.createUserWithEmailAndPassword(email, password);
}
function login(email, password) {
    return auth.signInWithEmailAndPassword(email, password);
}
function logout() {
    return auth.signOut();
}

useEffect(() => {
    const unsuscribe = auth.onAuthStateChanged(user => {
        setCurrentUser(user);
        setLoading(false);
        console.log(user, 'user'); // executes
    });

    return unsuscribe;
}, [setCurrentUser]);

//console.log(currentUser, 'cU1'); executes
const value = {
    currentUser,
    signup,
    login,
    logout,
};

return (
    <AuthContext.Provider value={value}>
        {(!loading && children) || Header}
    </AuthContext.Provider>
);

}; Header.js

import React, { useState } from 'react';
import { Nav, Navbar, Alert } from 'react-bootstrap';
import { Link, useHistory } from 'react-router-dom';
import { useAuth } from '../contexts/AuthContext';

const Header = () => {
   const [error, setError] = useState('');
   const { logout, currentUser, login } = useAuth() || {};

const history = useHistory();
const myStyle = {
    zIndex: 200,
};

console.log(currentUser, logout, 'cU'); //shows undefined

async function handleLogout(e) {
    e.preventDefault();
    setError('');

    try {
        await logout();
        history.push('/');
    } catch (err) {
        console.log(err, 'error');
        setError('Failed to logout');
    }
}

return (
    <div className='Header'>
        {error && (
            <Alert variant='danger' style={myStyle}>
                {error}
            </Alert>
        )}
        <Navbar bg='dark' variant='dark' expand='lg' style={myStyle}>
            <Link to='/'>
                <Navbar.Brand>Photo-Terrace</Navbar.Brand>
            </Link>
            <Navbar.Toggle aria-controls='basic-navbar-nav' />
            <Navbar.Collapse id='basic-navbar-nav'>
                <Nav className='ml-auto mr-auto'>
                    <Link to='/'>
                        <Nav.Link href='#home'>Go to Your Photos</Nav.Link>
                    </Link>
                </Nav>
                <Nav className=' mr-100'>
                    <Link to='/signup'>
                        <Nav.Link href='#home'> Sign Up</Nav.Link>
                    </Link>
                    <Link to='/login'>
                        <Nav.Link href='#home'>Log In</Nav.Link>
                    </Link>
                    <Link to='/update-profile'>
                        <Nav.Link href='#home'>Update Profile</Nav.Link>
                    </Link>
                    <Link to='/'>
                        <Nav.Link href='#home' onClick={handleLogout}>
                            Log Out
                        </Nav.Link>
                    </Link>
                </Nav>
            </Navbar.Collapse>
        </Navbar>
    </div>
);
};

export default Header;

Login.js

import React, { useRef } from 'react';
import { useState } from 'react';
import { Card, Form, Button, Alert } from 'react-bootstrap';
import { useAuth } from '../contexts/AuthContext';
import { Link, useHistory } from 'react-router-dom';

export const Login = () => {
const emailRef = useRef();
const passwordRef = useRef();
const { login, currentUser, logout } = useAuth();
const [error, setError] = useState('');
const [loading, setLoading] = useState(false);
const history = useHistory();

async function handleSubmit(e) {
    e.preventDefault();

    try {
        setError('');
        setLoading(true);
        await login(emailRef.current.value, passwordRef.current.value);
        history.push('/');
        //console.log(currentUser, logout, 'login') //executes;
    } catch {
        setError('Either email or password does not exist');
    }
    setLoading(false);
}

return (
    <>
        <Card>
            <Card.Body>
                <h2 className='text-center mb-4'>Login</h2>
                {error && <Alert variant='danger'>{error}</Alert>}
                <Form>
                    <Form.Group id='email'>
                        <Form.Label>Email</Form.Label>
                        <Form.Control type='email' ref={emailRef} required />
                    </Form.Group>
                    <Form.Group id='password'>
                        <Form.Label>Password</Form.Label>
                        <Form.Control type='password' ref={passwordRef} required />
                    </Form.Group>
                    <Button
                        onClick={handleSubmit}
                        disabled={loading}
                        type='submit'
                        className='w-100'
                    >
                        Log In
                    </Button>
                </Form>
            </Card.Body>
        </Card>
        <div className='w-100 text-center mt-2'>
            Need an account? <Link to='/signup'>Sign up</Link>
        </div>
    </>
);
};

Signup.js is mostly the same //executes is when it shows the whole object completely. In Header.js const{logout, currentUser} shows undefined whereas the same show perfectly as to be in Login and Signup. What should be done? I thought it was because of children in AuthContext so I tried to add Header in AuthContext.Provider too but it doesn't work.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
等待大神解答

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...