简体   繁体   中英

React component not re-render when a store variable is dispatched in redux

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;

When this program starts the variable lodaing is true; so component is rendered. After the datafecter is runned variable lodaing becomes false and isLoged becomes true.

Initially isLoged was false; and I obtained it from redux store. When I dispached it in between into true, it changes its value to true (I saw the value change in react dev tool). But it is not rerendering it's value.

ie, if lodaing is false and isLoged is true I should get the component. But unfortunately I'm getting error component.This means that isLoged's value is not rendered.

HOW TO SOLVE THIS REDUX RERENDERING ISSUE?

This problem might be caused by the delay that React takes to update the local state completely, so you need to use useEffect to dispatch your action only when the state loading has changed. So:

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM