Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

useContext Cannot read properties of undefined (reading 'name')

I am saving a user object into the browser cookies and want to read its properties in the frontend.
The error I am getting is:

Cannot read properties of undefined (reading 'name')
TypeError: Cannot read properties of undefined (reading 'name')
    at ProfileCard (http://localhost:3000/main.2a650ebd2579fa9c50cd.hot-update.js:56:26)

userContext.jsx

import axios from 'axios';
import { createContext, useState, useEffect } from 'react';

export const UserContext = createContext({});

export function UserContextProvider({ children }) {
    const [user, setUser] = useState(null);
    useEffect(() => {
        if (!user) {
            axios.get('/profile').then(({ data }) => {
                setUser(data);
            });
        }
    }, []);

    return <UserContext.Provider value={user}>{children}</UserContext.Provider>;
}

index.js

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

import React from 'react';
import ReactDOM from 'react-dom/client';
import {
    BrowserRouter as Router,
    Routes,
    Route,
    Navigate,
} from 'react-router-dom';

import './index.css';

import App from './App';
import Signup from './pages/auth/Signup';
import Login from './pages/auth/Login';
import axios from 'axios';
import { Toaster } from 'react-hot-toast';
import { UserContextProvider } from './context/userContext';

axios.defaults.baseURL = 'http://localhost:8000';
axios.defaults.withCredentials = true;

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <UserContextProvider>
        <Toaster position='bottom-right' toastDuration={{ duration: 2000 }} />
        <Router>
            <Routes>
                <Route path='/dashboard' element={<App />} />
                <Route path='/signup' element={<Signup />} />
                <Route path='/login' element={<Login />} />
                <Route exact path='/' element={<Navigate to='/dashboard' />} />
            </Routes>
        </Router>
    </UserContextProvider>
);

ProfileCard.jsx

import React, { useState, useContext } from 'react';
import { Link } from 'react-router-dom';
import { UserContext } from '../../context/userContext';

export default function ProfileCard() {
    const [isProfileExpanded, setProfileExpanded] = useState(false);
    const { user } = useContext(UserContext);

    return (
                       ...
                        <a
                            className='block px-4 py-2 text-sm text-gray-700'
                            role='menuitem'
                        >
                            {user.name}
                        </a>
                       ...

The profile with the user gets stored in the browser like this:

{
    "email": "test@gmail.com",
    "id": "66599569fd060626919b7ed7",
    "name": "Luke",
    "iat": 1717685285
}

Why can’t I access these properties of the object? The route to the backend is working perfectly fine and giving back the correct data I need but I simply cannot access it in the frontend.

>Solution :

The value of useContext is exactly what you set it to in the provider. Sometimes that is an object with properties in it, but other times it is a singular value.

You have set it to be user, so the correct way to access the user through context would be

// const { user } = useContext(UserContext);
const user = useContext(UserContext);

You are getting an error because user is null, and by destructuring the value of the context, it’s actually trying to access a user property on the user (user.user -> null.user).

While making this change will fix this specific error, you will still need to account for the fact that user will be null initially, since later on in the component user.name will not work (null.name).

You can help this by setting the initial state to an empty object

const [user, setUser] = useState({});

or by accounting for it using the nullsafe operator (?.) in your component

const user = useContext(UserContext);
    
return (
  ...
  <a
    className='block px-4 py-2 text-sm text-gray-700'
    role='menuitem'
  >
    {user?.name}
  </a>
  ...
);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading