Skip to main content

Handling Initial State

This example demonstrates proper initialization of state when dealing with asynchronous data fetching in React.
Initially, the state post should not be left undefined, as it can lead to errors when trying to access its properties before the data is fetched. Instead, it's important to initialize it as null or with a default value.

Additionally, using conditional rendering with optional chaining (?.) prevents errors when accessing properties of an object that may still be null or undefined.
This ensures that the component does not break while waiting for the data to load. When using TypeScript, it's important to define the expected type of the state to ensure type safety, which also helps prevent assigning incorrect values to state variables.

import { useEffect, useState } from "react";

const SevenAndEight = () => {
// Initializing state with an object
const [post, setPost] = useState(null); // it's important not to leave the state undefined initially, as it could cause errors
const [loading, setLoading] = useState(true);

useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/posts/1")
.then((res) => res.json())
.then((data) => {
setPost(data);
setLoading(false);
});
}, []);

return (
<article>
{loading ? (
"Loading..."
) : (
<>
{/* Don't output like this */}
{/* <h1>{post.title}</h1> */}
{/* <p>{post.body}</p> */}
<h1>{post?.title}</h1>
<p>{post?.body}</p>
</>
)}
</article>
);
};

// use conditional rendering with the optional chaining operator (?)
export default SevenAndEight;

// ts -> js, jsx, ts, tsx files
// useState(true) -> TypeScript will infer that this is a boolean value
// this also means you cannot assign values of other types to this boolean variable, etc.

/* TypeScript mistakes
type Post = {
title: string;
body: string;
}

const [post, setPost] = useState<Post | null>(null);
*/