React Redux,useSelector导致组件渲染两次。

3

我正在尝试为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);,那么组件只会渲染一次,正如我所期望的那样,我不明白为什么上面的代码会导致它渲染两次! 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;


感谢您!

userData 是如何填充的? - Jayce444
1个回答

5
你的实现问题在于渲染组件后设置用户状态,即在 App.js 中使用 useEffect 设置用户状态。
第一次呈现时,用户状态为 null -> useEffect 会派发从本地存储中检索到的用户数据 -> 用户状态得到更新 -> 另一次呈现,因为你正在监听状态更改。
如果你想使用本地存储设置用户数据,我建议在初始化 redux 状态时这样做。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接