#reactjs #redux #react-redux #react-hooks
#reactjs #redux #react-redux #реагирующие хуки
Вопрос:
Я пытаюсь создать пользовательскую область для приложения react,
Если пользователь вошел в систему, данные сохраняются в redux в разделе «userData»,
Проблема, с которой я столкнулся, заключается в том, что если пользователь обращается к области пользователя, когда он не вошел в систему, я хочу, чтобы приложение перенаправляло их на другую страницу notloggedin,
У меня есть приведенное ниже, однако проблема, с которой я столкнулся, заключается в том, что при первом рендеринге маршрута userDetails
возвращается пустой объект, который впоследствии запускает history.push('/notloggedin')
. Я могу видеть, удаляю ли я history.push('/notloggedin')
и загружаю компонент в первый раз, когда он загружается userDetails
как пустой объект, но затем перенаправляется как заполненный объект. Я действительно застрял на том, как заставить компонент отображать только после того, как объект был заполнен из useSelector.
import React, {useState, useEffect} from 'react';
import {useSelector, shallowEqual} from 'react-redux';
const index = () => {
const userDetails = useSelector(state=>state.userData, shallowEqual);
useEffect(()=>{
if(Object.keys(userDetails).length===0){
history.push('/notloggedin')
}
},[])
return (
<div>
<h1>Member Area</h1>
<p>Your User name us</p>
{userDetails.username}
...
</div>
);
};
export default index;
если я удалю строку const userDetails = useSelector(state=>state.userData, shallowEqual);
, то компонент будет отображаться только один раз, как я и ожидал, я не понимаю, почему приведенное выше действие вызывает его рендеринг дважды!
Пользовательские данные заполняются с помощью приведенного ниже действия
//login/actions.js
export const getUserData = (token) => {
console.log('getuser data');
return dispatch => {
api.getUserData()
.then(res =>
dispatch({
type: GET_USER_DETAILS,
payload: res.data.user
})
);
};
};
который вызывается в App.js
//App.js
const App = () => {
const dispatch = useDispatch();
useEffect(() => {
if (localStorage.getItem("userToken")) {
dispatch(getUserData(localStorage.getItem("userToken")));
}
}, []);
return (
<div className="app">
...
</div>
);
};
export default App;
Спасибо!
Комментарии:
1. Как
userData
заполняется?
Ответ №1:
Проблема с вашей реализацией заключается в том, что вы устанавливаете свое пользовательское состояние после визуализации компонентов (вы устанавливаете пользовательское состояние с помощью useEffect
in App.js
).
Первый рендеринг с пользовательским состоянием null -> useEffect отправляет пользовательские данные, извлеченные из локального хранилища -> состояние пользователя обновляется -> другой рендеринг, поскольку вы прослушиваете изменение состояния.
Если вы хотите настроить свои пользовательские данные с использованием локального хранилища, я рекомендую сделать это при инициализации вашего состояния redux.