我正在构建一个具有登录功能的项目(待办应用程序), 在这个Home组件中,我必须判断本地存储中是否没有设置令牌,然后导航到登录组件,

但是在导航之后,Home组件仍然呈现,并且在该组件中我有一个API调用,因此由于在本地存储中找不到令牌,它抛出一个错误"Underated"

主页组件:发布的帖子:

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;

NotesContainer个组件中,我有API调用.

备注容器:

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>
                    &nbsp; 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;

在当前情况下,当我转到Home组件时,它将判断令牌,如果没有设置Token,则它将导航到Login组件,但Home组件仍在呈现,且由于我的API调用生成并引发错误.

enter image description here

因此,我希望如果没有在本地存储中设置令牌,那么在呈现Home组件之前导航到登录,这样我们就可以停止API调用.

推荐答案

您可以使用几个选项来避免NotesContainer组件中的getNotes调用.以下是一些建议.

  1. 仅当存在令牌值时才有条件地呈现NotesContainer组件.

    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();
    
      const token = localStorage.getItem("token");
    
      useEffect(() => {
        if (!token) {
          navigate("/login");
    
          // for toast
          toast.error("Please login", { .... });
        }
      }, [token]);
    
      return (
        <>
          <div className=" mt-4 px-2">
            <h1 className="text-4xl text-center font-semiboldbold underline underline-offset-2">
              Your Notes
            </h1>
          </div>
          <div>
            {token && <NotesContainer />}
          </div>
        </>
      );
    }
    
    export default Home;
    
  2. 有条件地呈现Home组件的内容,如果没有令牌,则为空.

    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();
    
      const token = localStorage.getItem("token");
    
      useEffect(() => {
        if (!token) {
          navigate("/login");
    
          // for toast
          toast.error("Please login", { .... });
        }
      }, [token]);
    
      if (!token) return null;
    
      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;
    
  3. 有条件地呈现Home组件的内容,如果没有令牌,则重定向.

    import React, { useEffect } from "react";
    import NotesContainer from "./NotesContainer";
    import { useNavigate, Navigate } from "react-router-dom";
    import { toast } from "react-toastify";
    
    function Home() {
      const navigate = useNavigate();
    
      const token = localStorage.getItem("token");
    
      useEffect(() => {
        if (!token) {
          // for toast
          toast.error("Please login", { .... });
        }
      }, [token]);
    
      if (!token) return <Navigate to="/login" replace />;
    
      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;
    
  4. 无条件地呈现Home组件的内容,包括NotesContainer组件,并在NotesContainer中判断令牌.

    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();
    
      const token = localStorage.getItem("token");
    
      useEffect(() => {
        if (!token) {
          navigate("/login");
    
          // for toast
          toast.error("Please login", { .... });
        }
      }, [token]);
    
      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;
    
    function NotesContainer() {
      const {
        notes,
        setAdding,
        setIsOpen,
        setCurrentNote,
        getNotes
      } = useContext(NoteContext);
    
      useEffect(() => {
        const token = localStorage.getItem("token");
    
        if (token) {
          getNotes();
        }
      }, []);
    
      return (
        ....
      );
    }
    

Javascript相关问答推荐

vue3类型脚本中可能未定义对象''

如何制作删除按钮以从列表中删除该项目所属的项目?

使用Apps Script缩短谷歌表中的URL?

如何指定1条记录1个表?

如何修复内容安全策略指令脚本-SRC自身错误?

*ngFor和@代表输入decorator 和选角闭合

如何使用Echart 5.5.0创建箱形图

如何用显示网格平滑地将元素从一个地方移动到另一个地方?

React Code不在装载上渲染数据,但在渲染上工作

Snowflake JavaScript存储过程返回成功,尽管预期失败

colored颜色 检测JS,平均图像 colored颜色 检测JS

Regex结果包含额外的match/group,只带一个返回

如何避免页面第一次加载时由于CSS样式通过JavaScript更改而出现闪烁

如何在coCos2d-x中更正此错误

在WordPress中使用带有WPCode的Java代码片段时出现意外令牌错误

如何防止ionic 输入中的特殊字符.?

我想使用GAS和HTML将从Electron 表格中获得的信息插入到文本字段的初始值中

P5.js中矩形内的圆弧

P5play SecurityError:无法从';窗口';读取命名属性';Add';:阻止具有源的帧访问跨源帧

固定动态、self 调整的优先级队列