首页 > 解决方案 > 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;

谢谢!

标签: reactjsreduxreact-reduxreact-hooks

解决方案


您的实现的问题在于,一旦呈现组件,您就设置了用户状态(您正在使用useEffectin设置用户状态App.js)。

用户状态为 null 的第一次渲染 -> useEffect 调度从本地存储中检索到的用户数据 -> 用户状态得到更新 -> 因为您正在监听状态更改,所以另一个渲染。

如果你想使用本地存储设置你的用户数据,我建议在初始化你的 redux 状态时这样做。


推荐阅读