在 redux 中调度存储变量时,React 组件不会重新渲染

Posted

技术标签:

【中文标题】在 redux 中调度存储变量时,React 组件不会重新渲染【英文标题】:React component not re-render when a store variable is dispatched in redux 【发布时间】:2021-07-21 04:32:50 【问题描述】:
import React,  useEffect, useState  from 'react';
import  useDispatch, useSelector  from 'react-redux';
import  useHistory  from 'react-router-dom';

import  logedInAction  from '../../redux/userDetails/userDetailsActions';

import Loading from '../Loading/Loading';
import ChatList from './ChatList/ChatList';

const MainWindow = () => 
    const  isLoged  = useSelector( state => state.userDetails );
    const dispatch = useDispatch();
    const history = useHistory();

    const [ loading , setLoading ] = useState(true);

    useEffect( () =>  
        const dataFetcher = async () => 
            try 
                const res = await fetch( "http://localhost:4000/" ,  credentials: 'include' );
                // doing some code and dispatching isLoged variable to true
                setLoading(false);
             catch(e)  console.log(e); 
        
        dataFetcher();
     , [ dispatch , history ] );

    return(
        <>
            
                loading ? <Loading  /> : 
                isLoged ? <ChatList /> : <div> error</div>
            
        </>
    );


export default MainWindow;

当这个程序启动时,变量 lodaing 为 true ;所以组件被渲染。 运行 datafecter 后,变量 lodaing 变为 false,isLoged 变为 true。

最初 isLoged 为 false ;我从 redux 商店获得了它。当我将它发送到 true 之间时,它会将其值更改为 true (我在反应开发工具中看到了值的变化)。但它并没有重新渲染它的价值。

ie,如果 lodaing 为 false 而 isLoged 为 true,我应该得到组件。但不幸的是,我收到了错误组件。这意味着 isLoged 的​​ 值未呈现。

如何解决这个 REDUX 渲染问题?

【问题讨论】:

【参考方案1】:

这个问题可能是由 React 完全更新本地状态所花费的延迟引起的,因此只有当状态 loading 发生变化时,您才需要使用 useEffect 来调度您的操作。所以:

import React,  useEffect, useState  from 'react';
import  useDispatch, useSelector  from 'react-redux';
import  useHistory  from 'react-router-dom';

import  logedInAction  from '../../redux/userDetails/userDetailsActions';

import Loading from '../Loading/Loading';
import ChatList from './ChatList/ChatList';

const MainWindow = () => 
    const  isLoged  = useSelector( state => state.userDetails );
    const dispatch = useDispatch();
    const history = useHistory();

    const [ loading , setLoading ] = useState(true);

    useEffect( () =>  
        const dataFetcher = async () => 
            try 
                const res = await fetch( "http://localhost:4000/" ,  credentials: 'include' );
                setLoading(false);
             catch(e)  console.log(e); 
        
        dataFetcher();
     , [ dispatch , history ] );

    useEffect( () =>  
       // this "if" guarantee that the local state `loading` and the store state `isLoged` will be false at this point
       if(!loading && !isLoged) 
         // doing some code and dispatching isLoged variable to true
       
       
     , [ loading ] );

    return(
        <>
            
                loading ? <Loading  /> : 
                isLoged ? <ChatList /> : <div> error</div>
            
        </>
    );


export default MainWindow;

【讨论】:

以上是关于在 redux 中调度存储变量时,React 组件不会重新渲染的主要内容,如果未能解决你的问题,请参考以下文章

在React / Redux中,如果函数组件正在使用redux-thunk调度函数,则如何setIsLoading()?

来自根组件的 React/Redux 调度操作?

在 react-admin 中获得对 redux 存储的访问权限

Redux dispatch 导致组件本地状态重置

React + redux:连接组件加载时调用调度

使用 TypeScript 在 React 组件外部调度 Redux Thunk 操作