Home > Software engineering >  React todo app Login page appears for a moment even though logged in
React todo app Login page appears for a moment even though logged in

Time:09-12

I have a CRUD todo application where the user logs in if they are not logged in and this is stored locally. Also todo app making CRUD operations via API. But even if the user is logged in, when the page is refreshed, the login screen appears and disappears for a moment. How can I solve this?

  const [todoList, setTodoList] = useState([]);
  const [newTask, setNewTask] = useState("");
  const [todoEditing, setTodoEditing] = useState(null);
  const [editingText, setEditingText] = useState("");
  const [username, setUsername] = useState("");
  const [savedUsername, setSavedUsername] = useState("");
  const [theme, setTheme] = useState("light");
  const [addLoading, setAddLoading] = useState(false); // when adding a todo loading spinner appears in button
  const [todoLoading, setTodoLoading] = useState(null); //when crud operations happen a loading spinner appears in todo cards
  const [loading, setLoading] = useState(false); // loading state for crud functions 
  const [loginLoading, setLoginLoading] = useState(false); // loading screen for app rendering

useEffect(() => {
    setLoginLoading(true);
    const storageUsername = localStorage.getItem("username");
    if (storageUsername) {
      setSavedUsername(storageUsername);
    }

    setLoginLoading(false);
  }, []);

<ThemeContext.Provider value={{ theme }} style={{ position: "relative" }}>
      {savedUsername ? (
        <div className="container">
.... Components
</div>  ) : (
        <div className="login-container" id={theme}>
          {loginLoading ? (
            <Loading />
          ) : (
            <Login
              handleChange={setUsername}
              handleLogin={handleLogin}
              value={username}
            />
          )}
        </div>
      )}
    </ThemeContext.Provider>

CodePudding user response:

Your effect from useEffect is only executed after your first render. So your first state for the loginLoading is false then true and then false again. This should fix it:

  const [todoList, setTodoList] = useState([]);
  const [newTask, setNewTask] = useState("");
  const [todoEditing, setTodoEditing] = useState(null);
  const [editingText, setEditingText] = useState("");
  const [username, setUsername] = useState("");
  const [savedUsername, setSavedUsername] = useState("");
  const [theme, setTheme] = useState("light");
  const [addLoading, setAddLoading] = useState(false); // when adding a todo loading spinner appears in button
  const [todoLoading, setTodoLoading] = useState(null); //when crud operations happen a loading spinner appears in todo cards
  const [loading, setLoading] = useState(false); // loading state for crud functions 
  const [loginLoading, setLoginLoading] = useState(true); // loading screen for app rendering

useEffect(() => {
    const storageUsername = localStorage.getItem("username");
    if (storageUsername) {
      setSavedUsername(storageUsername);
    }

    setLoginLoading(false);
  }, []);

<ThemeContext.Provider value={{ theme }} style={{ position: "relative" }}>
      {savedUsername ? (
        <div className="container">
.... Components
</div>  ) : (
        <div className="login-container" id={theme}>
          {loginLoading ? (
            <Loading />
          ) : (
            <Login
              handleChange={setUsername}
              handleLogin={handleLogin}
              value={username}
            />
          )}
        </div>
      )}
    </ThemeContext.Provider>

But, to improve even more, I wouldn't use a loading state for the login because localStorage.getItem("username") is a synchronous operation that can be performed more elegantly like that:

  const [todoList, setTodoList] = useState([]);
  const [newTask, setNewTask] = useState("");
  const [todoEditing, setTodoEditing] = useState(null);
  const [editingText, setEditingText] = useState("");
  const [username, setUsername] = useState("");
  const [savedUsername, setSavedUsername] = useState(() => localStorage.getItem("username") || "");
  const [theme, setTheme] = useState("light");
  const [addLoading, setAddLoading] = useState(false); // when adding a todo loading spinner appears in button
  const [todoLoading, setTodoLoading] = useState(null); //when crud operations happen a loading spinner appears in todo cards
  const [loading, setLoading] = useState(false); // loading state for crud functions 

<ThemeContext.Provider value={{ theme }} style={{ position: "relative" }}>
      {savedUsername ? (
        <div className="container">
.... Components
</div>  ) : (
        <div className="login-container" id={theme}>
          <Login
            handleChange={setUsername}
            handleLogin={handleLogin}
            value={username}
          />
        </div>
      )}
    </ThemeContext.Provider>
  • Related