Search code examples
react-nativereduxreact-reduxuse-effect

useEffect not triggered


I'm trying to use redux with useEffect to update/get the redux state but useEffect is totally not running at all but I have no idea what is going on. I can't even get the "hi"

import { useSelector, useDispatch } from 'react-redux';
import { setDisplayLogsheet, getLogsheets } from '../redux/actions';   

...

const { displayLogsheet, logsheets } = useSelector(state => state.logsheetReducer);
const dispatch = useDispatch();
    
useEffect(() => {
    console.log("hi")
    dispatch(getLogsheets());
    dispatch(setDisplayLogsheet(logsheets));
}, []);

Any help please? Thanks


UPDATE: here's more code to understand

App.js:

I have added the store inside the provider

    const Stack = createStackNavigator();

    export default function App() {
      return(
        <Provider store={Store}>
          <NavigationContainer>
          ...
       <Provider />

    }

home.js:

tried to useSelector to get the logsheets and displayLogsheets and useEffect to dispatch, but the the useEffect is totally not running

    export default function Home({navigation})  {
        
        const { displayLogsheet, logsheets } = useSelector(state => state.logsheetReducer);
        const dispatch = useDispatch();
        
        useEffect(() => {
            console.log('getting logsheets...')
            dispatch(getLogsheets())
          }, [dispatch])
          
        useEffect(() => {
            console.log('setting displayLogsheet...')
            if(logsheets){ 
                dispatch(setDisplayLogsheet(logsheets))
            }
        }, [dispatch, logsheets])
    
    
        console.log(logsheets)
        console.log(displayLogsheet)

        return (
            <>

            <SafeAreaView>
                <ScrollView>
                    <HomeTopStack logsheet={displayLogsheets} iterateDocket={iterateDocket} />
                    <ScanBarcodeButton navigation={navigation} />
                    {displayLogsheets.data.DO.map(logsheet => (
                        <TouchableOpacity onPress={() => navigation.navigate('Details', logsheet)}>
                            <DOCards logsheet={displayLogsheets} />
                        </TouchableOpacity>
                    ))}
                </ScrollView>
            </SafeAreaView>
            </>
        )
    }

store.js:

    import { createStore, combineReducers, applyMiddleware } from 'redux';
    import thunk from 'redux-thunk';
    import logsheetReducer from './reducers';
    
    const rootReducer = combineReducers({ logsheetReducer });
    
    export const Store = createStore(rootReducer, applyMiddleware(thunk));

reducer.js:

this is the reducer to set display logsheet and also to get the dummy logsheet data


    import { SET_DISPLAY_LOGSHEET, GET_LOGSHEETS } from "./actions";
    
    const initialState = {
        logsheets: {},
        displayLogsheet: {},
    }
    
    function logsheetReducer(state = initialState, action) {
        switch (action.type) {
            case SET_DISPLAY_LOGSHEET:
                console.log("inside logsheetReducer, SET_DISPLAY_LOGSHEET")
                return { ...state, displayLogsheet: action.payload };
            case GET_LOGSHEETS:
                console.log("inside logsheetReducer, GET_LOGSHEET")
                return { ...state, logsheets: action.payload };
            default:
                return state;
        }
    }
    
    export default logsheetReducer;

actions.js:


    import CreateFakeLogsheets from "../data/logsheet";
    
    export const SET_DISPLAY_LOGSHEET = 'SET_DISPLAY_LOGSHEET';
    export const GET_LOGSHEETS = 'GET_LOGSHEETS';
    
    const logsheets = CreateFakeLogsheets(2,3)
    
    export const getLogsheets = () => {
        console.log("inside getLogsheets")
        try {
            return dispatch => {
                dispatch({
                    type: GET_LOGSHEETS,
                    payload: logsheets
                })
            }
        } catch (error) {
            console.log(error)
        }
    }
    
    export const setDisplayLogsheet = displayLogsheet => {
        console.log("inside setDisplayLogsheets")
    
        return dispatch => {
            dispatch({
                type: SET_DISPLAY_LOGSHEET,
                payload: displayLogsheet
            });
        }
    };

here's most of the code with redux and also the useEffect. Any help please


Solution

  • Without knowing how the rest of the code is structured, I would split the effect in two, like this:

    useEffect(() => {
      console.log('getting logsheets...')
      dispatch(getLogsheets())
    }, [dispatch])
    
    useEffect(() => {
      console.log('setting displayLogsheet...')
      if(logsheets){ // only dispatch this if logsheets have been fetched
        dispatch(setDisplayLogsheets(logsheets))
      }
    }, [dispatch, logsheets])