D
D
Dubolom Unicellular2020-07-21 22:37:08
JavaScript
Dubolom Unicellular, 2020-07-21 22:37:08

Will react-router-dom re-render the page if I pass useState a value?

Hello.
I have my own hook called auth. From it I get token, ready and other parameters (but the token is more important in the question)
There is an authorization page for the jwt token.
There are also routes that accept the isAuth parameter, if it is true (truthy), then the react router dom renders the page of the authorized user (the main functions of the application are available to him), if the token is false (falsy), then the application registration/login form is displayed.
When the user enters the account (there is a form in which he presses the button), the generated token is written to the token (it is stored in localstorage) but the routes are not redrawn! Although the token is wrapped in useState(). It should redirect to /home and render the HomePage. However, this does not happen.
(After refreshing the page, everything works)

Here is a snippet from App.js:

import React, {useState, useEffect} from "react";
import {BrowserRouter as Router} from "react-router-dom";
// routes
import {useRoutes} from "./routes";
// hooks
import {useAuth} from "./hooks/auth.hook";
// context
import {AuthContext} from "./context/auth.context";
// components
import {Loader} from "./components/Loader";

function App() {
  const {login, logout, token, userId, ready} = useAuth();
  const isAuth = !!token; // "!!" - прикладываю к boolean
  const routes = useRoutes(isAuth); // token обернут в useState, но редиректа после авторизации нет
  ...


Here is auth.hook.js:
import {useState, useCallback, useEffect} from "react";

const storageName = "user";

export const useAuth = () => {
  const [token, setToken] = useState(null); // как и говорил, он обернут в useState
  const [userId, setUserId] = useState(null);
  const [ready, setReady] = useState(false);

  const login = useCallback((jwtToken, id) => {
    setToken(jwtToken);
    setUserId(id);

    localStorage.setItem(storageName, JSON.stringify({
      token: jwtToken, userId: id
    }));
  }, []);

  const logout = useCallback(() => {
    setToken(null);
    setUserId(null);

    localStorage.removeItem(storageName);
  }, []);

  useEffect(() => {
    const user = JSON.parse(localStorage.getItem(storageName));

    if(user && user.token){
      login(user.token, user.userId);
    }
    setReady(true);
  }, [login]);

  return {login, logout, token, userId, ready}
}


What to do?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
A
Alexey, 2020-07-21
@AleksRap

First of all. Logic with authorization does not make sense to put in a hook, because it is used once. Custom hooks are needed to reuse logic involving built-in react hooks.
Secondly, do not store the token in localStorage, store it in the application's memory
. Thirdly, I highly recommend starting to use redux. It is much more convenient to store such a state in it.
As a matter of fact, check whether the isAuth state changes with the usual console.log. If it changes, the problem is in your useRoutes hook.

V
Vladimir, 2020-07-22
@HistoryART

I agree with the answer above, I have a state for each component during authorization and that's it)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question