I am building one Project (To-Do-App) with login functionality,
In this Home
component I have to check if token is not set in the localStorage, then navigate to login component,
But after the navigate, Home
component still renders and in this component I have an API call, so because of the token not found in localStorage, it throws an error "Unauthorized"
Home Component:
import React, { useEffect } from "react";
import NotesContainer from "./NotesContainer";
import { useNavigate } from "react-router-dom";
import { toast } from "react-toastify";
function Home() {
const navigate = useNavigate();
useEffect(() => {
if (!localStorage.getItem("token")) {
navigate("/login");
// for toast
toast.error("Please login", {
position: "top-right",
autoClose: 5000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
theme: "dark",
});
}
}, []);
return (
<>
<div className=" mt-4 px-2">
<h1 className="text-4xl text-center font-semiboldbold underline underline-offset-2">
Your Notes
</h1>
</div>
<div>
<NotesContainer />
</div>
</>
);
}
export default Home;
Inside NotesContainer
Component I have API call.
NotesContainer:
import React, { useContext, useEffect } from "react";
import Note from "./Note";
import NoteModal from "./NoteModal";
import NoteContext from "../context/notes/NoteContext";
function NotesContainer() {
const { notes, setAdding, setIsOpen, setCurrentNote, getNotes } =
useContext(NoteContext);
useEffect(() => {
getNotes();
}, []);
return (
<div className="px-3">
<NoteModal />
<div className="text-center mt-2 sm:text-end sm:mt-0npm st">
<button
onClick={() => {
setCurrentNote({ title: "", description: "" });
setAdding(true);
setIsOpen(true);
}}
className="bg-slate-700 rounded-lg text-white text-md p-2 hover:scale-105"
>
<span className="fas fa-plus "> </span>
Add New Note
</button>
</div>
<div className="mt-3 flex justify-evenly flex-wrap gap-3">
{notes.map((note) => (
<Note key={note._id} note={note} />
))}
</div>
</div>
);
}
export default NotesContainer;
In current scenario, when I go to home component it will check for token, and if token is not set then it will navigate to Login
component, but still home component is rendering and because of that my API call generate and throw an error.
So, I want that if token is not set in the localStorage then navigate to login before rendering the Home
component so we can stop that API call.
3
Answers
Rather than wait for your component to mount and run the effect hook (which is too late), use conditional rendering to render a
<Navigate>
component.This will avoid rendering your
<NotesContainer>
and thus any unauthenticated API calls.There are several options available to you to avoid the
getNotes
call in theNotesContainer
component. Here are a few suggestions.Conditionally render the
NotesContainer
component only if there is a token value.Conditionally render the
Home
component’s content or null if there is no token.Conditionally render the
Home
component’s content or redirect if there is no token.Unconditionally render the
Home
component’s content, including theNotesContainer
component, and check for the token inNotesContainer
.Make it simple and easy:
It will be better to use Context API to make a global auth state