Explicação detalhada do código:
Este código implementa um contexto (UserContext
) para gerenciar a autenticação de um usuário, fornecendo informações sobre o usuário e o estado de carregamento. Ele também permite o logout do usuário e a recuperação de informações de usuário a partir de uma API.
Estrutura do código:
-
Importações:
createContext
,useContext
,useState
,useEffect
do React: Para criar o contexto, armazenar o estado do usuário e controlar o ciclo de vida do componente.useRouter
donext/navigation
: Para redirecionar o usuário após o logout.
-
Contexto de Usuário:
- O contexto
UserContext
é criado usandocreateContext
. Ele armazena os dados do usuário, o estado de carregamento e as funçõesfetchUser
elogout
.
- O contexto
-
useUser
Hook:- O hook
useUser
permite que outros componentes acessem o contexto do usuário, facilitando o consumo de informações de autenticação.
- O hook
-
Componente
UserProvider
:UserProvider
é um componente de contexto que envolve outros componentes da aplicação, permitindo o acesso aos dados do usuário em qualquer parte da árvore de componentes.- Estado de Usuário: O estado
user
armazena os dados do usuário e o estadoloading
indica se a recuperação dos dados ainda está em andamento. - Função
fetchUser
: Faz uma requisição à API para recuperar os dados do usuário, incluindo a verificação de token no armazenamento local para autenticação. - Função
logout
: Remove o token do armazenamento local e redireciona o usuário para a página de login.
-
useEffect
:useEffect
é usado para chamar a funçãofetchUser
assim que o componente for montado, garantindo que as informações do usuário sejam carregadas ao iniciar a aplicação.
-
Retorno:
- O
UserContext.Provider
envolve os filhos (children
) e fornece o contexto com os dados do usuário, estado de carregamento, e as funçõesfetchUser
elogout
.
- O
Emojis:
- 🔐 para representar autenticação e segurança.
- 🛑 para o logout.
- 🕵️♂️ para a busca de dados do usuário.
- ⏳ para o estado de carregamento.
Código completo:
'use client'
import { createContext, useContext, useState, useEffect } from 'react'
import { useRouter } from 'next/navigation'
const UserContext = createContext()
export const useUser = () => {
return useContext(UserContext)
}
export const UserProvider = ({ children }) => {
const [user, setUser] = useState(null)
const [loading, setLoading] = useState(true)
const router = useRouter()
const fetchUser = async () => {
try {
const token = localStorage.getItem('token')
if (!token) {
throw new Error('Usuário não autenticado.')
}
const apiUrl = process.env.NEXT_PUBLIC_SERVER_URL
const response = await fetch(`${apiUrl}/api/alunos/me`, {
method: 'GET',
headers: {
Authorization: `Bearer ${token}`,
},
})
if (!response.ok) {
throw new Error('Erro ao buscar usuário.')
}
const data = await response.json()
console.log('UserProvider data:', data)
setUser(data)
} catch (error) {
console.error('Erro ao buscar usuário:', error)
setUser(null)
} finally {
setLoading(false)
}
}
useEffect(() => {
fetchUser()
}, [])
const logout = () => {
localStorage.removeItem('token')
setUser(null)
router.push('/login')
}
return (
<UserContext.Provider value={{ user, loading, fetchUser, logout }}>
{children}
</UserContext.Provider>
)
}