reactjs - React Redux,useSelector 导致组件渲染两次
问题描述
我正在尝试为反应应用程序创建一个用户区域,
如果用户已登录,则数据将存储在 redux 中的 'userData' 下,
我遇到的问题是,如果用户在未登录时对用户区域进行操作,我希望应用程序将他们重定向到另一个“未登录”页面,
我有以下内容,但是我遇到的问题是当路线首次呈现时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);
,那么组件只会按我的预期渲染一次,我不明白为什么上面的 live 会导致它渲染两次!
userData 填充了以下操作
//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;
谢谢!
解决方案
您的实现的问题在于,一旦呈现组件,您就设置了用户状态(您正在使用useEffect
in设置用户状态App.js
)。
用户状态为 null 的第一次渲染 -> useEffect 调度从本地存储中检索到的用户数据 -> 用户状态得到更新 -> 因为您正在监听状态更改,所以另一个渲染。
如果你想使用本地存储设置你的用户数据,我建议在初始化你的 redux 状态时这样做。
推荐阅读
- wordpress - 使用功能修改 Wordpress 电子邮件文本
- typescript - Typescript 获取特定的函数参数类型
- c# - 如何从我的 c# 控制器设置自定义字体大小
- c# - Wpf DataGrid通过列表属性动态设置列
- javascript - 有没有办法将对象存储在 mySQL 数据库中?
- ruby-on-rails - 如何有选择地停用 Rails I18n translation_missing spans?
- guava - 如何在 Guava Multimap 中不允许空键?
- rstudio - 我该如何解决:错误:找不到对象'a'
- jenkins - Helm 动态设置 Docker 镜像标签
- swift - swift 5中的谷歌地图中未显示多个制造商标题