skip to Main Content

using traditional ways of accessing objects with dot notation {quote.text} {quote.author} i’m receiving a "cannot read properties of null" error

import { useState, useEffect } from 'react';
import "./React.css";


   
function getRandomQuote(quotes) {
    return quotes[Math.floor(Math.random() * quotes.length)];
  }
  
  export default function App() {
    const [quotes, setQuotes] = useState([]);
    const [quote, setQuote] = useState(null);
  
    useEffect(() => {
      fetch("https://type.fit/api/quotes")
        .then((res) => res.json())
        .then((json) => {
          setQuotes(json);
          setQuote(json[0]);
        });
    }, []);
  
    function getNewQuote() {
      setQuote(getRandomQuote(quotes));
    }

  
    return (
      <main>
        <h1>Project 3: Quote Generator</h1>
        <section>
          <button onClick={getNewQuote}>New Quote</button>
          <h3>
            {quote.text}
          </h3>
          <i>- {quote.author}</i>
        </section>
      </main>
    );
  }

When I tried question mark with dot notation {quote?.text} {quote?.author} I got back my intented results. What was causing the error with regular dot notation?

import { useState, useEffect } from 'react';
import "./React.css";


   
function getRandomQuote(quotes) {
    return quotes[Math.floor(Math.random() * quotes.length)];
  }
  
  export default function App() {
    const [quotes, setQuotes] = useState([]);
    const [quote, setQuote] = useState(null);
  
    useEffect(() => {
      fetch("https://type.fit/api/quotes")
        .then((res) => res.json())
        .then((json) => {
          setQuotes(json);
          setQuote(json[0]);
        });
    }, []);
  
    function getNewQuote() {
      setQuote(getRandomQuote(quotes));
    }

  
    return (
      <main>
        <h1>Project 3: Quote Generator</h1>
        <section>
          <button onClick={getNewQuote}>New Quote</button>
          <h3>
            {quote?.text}
          </h3>
          <i>- {quote?.author}</i>
        </section>
      </main>
    );
  }

2

Answers


  1. The reason for having a ? is that this variable could be null.
    Since quote was null, that’s why you were getting this error.

    At first, it will be null:

    const [quote, setQuote] = useState(null);
    

    Then when you call getNewQuote it won’t be null anymore, but at first it will

    Login or Signup to reply.
  2. With const [quote, setQuote] = useState(null);, the inital state for quote is set to null. On the first render (note that the useEffect callback is executed after render), you will be trying to access null.text; this clearly causes an error.

    As you’ve found, using optional chaining is one way to fix it. Another method would be set the initial state to an empty object (useState({})): that way, you can access properties on it and get undefined which will result in nothing being rendered in that spot.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search