Имеется такой reducer для пользователя:
const defaultState = {
user: {},
auth: false
}
const SET_USER = 'SET_USER'
const SET_AUTH = 'SET_AUTH'
function userReducer(state = defaultState, action) {
switch(action.type) {
case SET_USER: return {...state, user: action.payload}
case SET_AUTH: return {...state, auth: action.payload}
default: return state
}
}
export function SET_USER_ACTION(payload) {
return {type: SET_USER, payload}
}
export function SET_AUTH_ACTION(payload) {
return {type: SET_AUTH, payload}
}
export default userReducer
И такой хук для удобной работы с ним:
import axios from 'axios'
import {useDispatch, useSelector} from 'react-redux'
import { SET_USER_ACTION, SET_AUTH_ACTION} from '../store/reducers/user.reducer'
import UserService from '../services/user.service'
import {API_URL} from '../utils/axios'
function useUser() {
const dispatch = useDispatch()
const {user, auth} = useSelector((state) => state.userData)
async function signUp(email, password) {
try {
const response = await UserService.SignUp(email, password)
localStorage.setItem('accessToken', response.data.tokens.accessToken)
dispatch(SET_USER_ACTION(response.data.person))
dispatch(SET_AUTH_ACTION(true))
} catch (error) {
console.log(error.response.data.message)
}
}
async function signIn(email, password) {
try {
const response = await UserService.SignIn(email, password)
localStorage.setItem('accessToken', response.data.tokens.accessToken)
dispatch(SET_USER_ACTION(response.data.person))
dispatch(SET_AUTH_ACTION(true))
} catch (error) {
console.log(error.response.data.message)
}
}
async function signOut() {
try {
await UserService.SignOut()
localStorage.removeItem('accessToken')
dispatch(SET_USER_ACTION({}))
dispatch(SET_AUTH_ACTION(false))
} catch (error) {
console.log(error.response.data.message)
}
}
async function checkAuth() {
try {
const response = await axios.get('/api/common/persons/refresh', {withCredentials: true, baseURL: API_URL})
localStorage.setItem('accessToken', response.data.tokens.accessToken)
dispatch(SET_USER_ACTION(response.data.person))
dispatch(SET_AUTH_ACTION(true))
} catch (error) {
console.log(error.response.data.message)
}
}
return {user, auth, signUp, signIn, signOut, checkAuth}
}
export default useUser
Все что в данном случае делает UserService - отсылает запросы с помощью axios на мой api. И вот что конкретно происходит в корневом App:
import {useEffect, useState} from 'react'
import useUser from './hooks/use.user'
function App(props) {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const {auth, user, signUp, signIn, signOut, checkAuth} = useUser()
function submitSignUp() {
signUp(email, password)
}
function submitSignIn() {
signIn(email, password)
}
function submitSignOut() {
signOut()
}
useEffect(() => {
if (localStorage.getItem('accessToken')) {
checkAuth()
}
}, [])
if (auth) {
return (
<div>
<h1>Добро пожаловать, {user.email}!</h1>
<button type="button" onClick={submitSignOut}>Выйти</button>
</div>
)
}
return (
<form className="form">
<input name="email" type="email" value={email} onChange={(e) => setEmail(e.target.value)} />
<input name="password" type="password" value={password} onChange={(e) => setPassword(e.target.value)} />
<div className="row">
<button type="button" onClick={submitSignIn}>Вход</button>
<button type="button" onClick={submitSignUp}>Регистрация</button>
</div>
</form>
)
}
export default App
Но вот что в данном случае я вижу в запросах:
Их отправляется два. Причем первый отрабатывает как нужно и на сервере в логах отрабатывает также корректно. Но новые куки не успевают установиться, потому что отправляется новый запрос со старыми куками, который и отрабатывается некорректно.
То есть все что меня беспокоит - братья, как убрать второй запрос?)