Artigo original escrito por: Adebola Adeniran
Artigo original: How to Persist a Logged-in User in React
Traduzido e adaptado por: Daniel Rosa

Se você executar uma busca rápida no Google sobre persistência de um usuário conectado com React (ou sobre manter um usuário conectado em React), não encontrará muitos resultados com respostas diretas. Não existem, de fato, exemplos que seja fáceis de seguir sobre como conseguir isso. Assim, eu decidi que tinha de escrever este guia simplificado.

Você já deve ter feito uma pesquisa sobre isso e deve ter visto a palavra localStorage aparecendo por aí. Sim, usaremos localStorage, mas eu quero mostrar exatamente como isso é feito.

Algumas observações sobre o localStorage.

  1. localStorage é o banco de dados do navegador. Os dados ficam armazenados dentro do navegador, na memória do computador.
  2. localStorage é específico de uma origem. Em outras palavras, o localStorage (em português, armazenamento local) para um site da web não pode ser acessado por outro.

Configuração inicial

Vamos começar. Implantei um servidor simples com Express no Heroku para usar para fazer os testes desta aplicação.

  1. Crie uma aplicação em React e vá para o componente <App />.
  2. Instale o axios usando npm install axios e importe-o em <App />
  3. Em seguida, crie um formulário simples de login que aceite um nome de usuário e uma senha.
import React, { useState } from "react";
import axios from "axios";

const App = () => {
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");
  const [user, setUser] = useState()

  const handleSubmit = async e => {
    
  };

// Se houver um usuário, mostre a mensagem abaixo
  if (user) {
    return <div>{user.username} is logged in</div>;
    // "usuário" está conectado
  }

  // Se não houver um usuário, mostre o formulário de login
  return (
    <form onSubmit={handleSubmit}>
      <label htmlFor="username">Nome de usuário: </label>
      <input
        type="text"
        value={username}
        placeholder="insira um nome de usuário"
        onChange={({ target }) => setUsername(target.value)}
      />
      <div>
        <label htmlFor="password">Senha: </label>
        <input
          type="password"
          value={password}
          placeholder="insira uma senha"
          onChange={({ target }) => setPassword(target.value)}
        />
      </div>
      <button type="submit">Login</button>
    </form>
  );
};

export default App;

Como você pode ver, definimos uma função assíncrona handleSubmit para processar a solicitação de login. Também definimos um condicional que exiba a mensagem {user.username} is logged in se tivermos um usuário ou o formulário de login quando não o tivermos.

Em seguida, vamos completar a função. Ela funcionará com os passos abaixo:

  1. Enviar os detalhes de login ao servidor.
  2. Se houver sucesso na solicitação (async-await), armazenar as informações do usuário em localStorage e definir o state (estado) do usuário.

Lidando com o evento de login

Vamos definir o manipulador de eventos handleSubmit.

const handleSubmit = async e => {
  e.preventDefault();
  const user = { username, password };
  // enviar o nome de usuário e a senha ao servidor
  const response = await axios.post(
    "http://blogservice.herokuapp.com/api/login",
    user
  );
  // definir o state do usuário
  setUser(response.data)
  // armazenar o usuário em localStorage
  localStorage.setItem('user', response.data)
  console.log(response.data)
};

Observação: use um bloco try-catch para lidar com os erros em funções assíncronas.

Agora que escrevemos nossa função, você pode executar npm start para testar a aplicação. Faça o login com username: user2, password: password.

Você deve receber o seguinte como resposta: o userId, token e o username

image-52

Verifique se um usuário já está conectado

Em seguida, queremos achar uma maneira de conferir se um usuário está conectado sempre que a aplicação carregar. Para isso, usamos o hook useEffect.

 useEffect(() => {
    const loggedInUser = localStorage.getItem("user");
    if (loggedInUser) {
      const foundUser = JSON.parse(loggedInUser);
      setUser(foundUser);
    }
  }, []);

Lembre-se de usar um array de dependência vazio em seu hook useEffect para que ele confira se um usuário está conectado na primeira vez em que a aplicação carregar.

Agora, nossa aplicação deve funcionar perfeitamente. Obtemos a página abaixo após o usuário ter se conectado pela primeira vez e os detalhes do usuário estão armazenados. Se você atualizar a página, verá que o usuário permanece conectado e que a página de conexão segue sendo exibida.

image-55

Como dica adicional, aqui você vê como implementar a saída da aplicação (logout).

Implementação da funcionalidade de logout

Para sair da aplicação, simplesmente esvaziamos o state do usuário e removemos o usuário do localStorage.

Vamos implementar isso.

Primeiro, criamos um botão para o logout.

<button onClick={handleLogout}>Logout</button>

Em seguida, criamos a função de logout.

const handleLogout = () => {
    setUser({});
    setUsername("");
    setPassword("");
    localStorage.clear();
  };

Está pronto. Acabamos.

Aqui, você tem o link para o gist completo no GitHub. Você pode seguir o autor por lá para saber das atualizações.