1

So ive been scratching my head over this one. When i login the user is not immediately displayed and i still see login and signup even though the user was successfully logged in but when i refresh the page manually the user and logout gets displayed and everything works fine. What am i doing wrong?

const NavBar = (props) => {
    const { user, setUser } = useContext(AuthContext);

    useEffect(
        () => {
            const config = {
                headers: {
                    'Content-Type': 'application/json',
                    Authorization: `Bearer ${localStorage.getItem('authToken')}`
                }
            };

            fetch(`${process.env.REACT_APP_BACKEND}/api/private`, config)
                .then((res) => {
                    return res.json();
                })
                .then((data) => {
                    setUser(data);
                });
        },
        [ setUser ]
    );

    return (
        <nav className="navbar navbar-expand-lg navbar-dark" style={{ background: '#1F2128' }}>
            <div className="container-fluid container-lg">
                <div className="collapse navbar-collapse" id="navbarNav">   
                    {user && (
                        <ul className="navbar-nav" style={{ marginLeft: 'auto' }}>
                            <li className="nav-item">
                                <Link className="nav-link" aria-current="page" to="/private">
                                    {user.email}
                                </Link>
                            </li>
                            <li className="nav-item">
                                <Link className="nav-link" aria-current="page" to="/logout">
                                    Logout
                                </Link>
                            </li>
                        </ul>
                    )}
                    {!user && (
                        <ul className="navbar-nav" style={{ marginLeft: 'auto' }}>
                            <li className="nav-item">
                                <Link className="nav-link" aria-current="page" to="/login">
                                    Login
                                </Link>
                            </li>
                            <li className="nav-item">
                                <Link className="nav-link" to="/signup">
                                    Sign up
                                </Link>
                            </li>
                        </ul>
                    )}
                </div>
            </div>
        </nav>
    );
};

export default NavBar;

For the Context by default im setting the user as null.

const AuthState = (props) => {
    const [ user, setUser ] = useState(null);
    const value = useMemo(() => ({ user, setUser }), [ user, setUser ]);

    return <AuthContext.Provider value={value}>{props.children}</AuthContext.Provider>;
};

And also the context:

import { createContext } from 'react';

const authContext = createContext();

export default authContext;
skyboyer
  • 22,209
  • 7
  • 57
  • 64

2 Answers2

0

If you have a problem with the initial data loading, then try changing

[ setUser ] 

to

[]

I also think this article may help you if my answer doesn't help.

n7y
  • 92
  • 3
0

See Updating Context from a Nested Component

theme-context.js

// Make sure the shape of the default value passed to
// createContext matches the shape that the consumers expect!
export const ThemeContext = React.createContext({
  theme: themes.dark,
  toggleTheme: () => {},
});

You should provide an initial value to the context that matches what consumers should expect.

const authContext = createContext({
  user: null,
  setUser: () => {},
});
Drew Reese
  • 165,259
  • 14
  • 153
  • 181