question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Not getting updated state inside nested function

See original GitHub issue

I have been struggling with this problem for a while now and have narrowed it down to that it only happens inside a nested const function and can’t really see why. The state outputs as the initial one until i re-render the screen which i gets the updated state from redux with redux-persist. I change the state on Second screen and then use the goBack() function inside react navigation to reproduce the problem.

I feel like i am missing something and all help is greatly appriciated.

redux/slices.match.js

import { createSlice } from "@reduxjs/toolkit"

const initialState = {
    matchData: 0,
}

const matchSlice = createSlice({
    name: 'userMatch',
    initialState,
    reducers: {
        setMatchData: (state, action) => {
            state.matchData = action.payload.data;
        },
        setMatchDataReset: (state) => {
            state.matchData = 0;
        }
    }
});

export const { setMatchData, setMatchDataReset } = matchSlice.actions;

export const selectMatchData = (state) => state.userMatch.matchData;

export default matchSlice.reducer;

redux/store/index.js

import { configureStore } from '@reduxjs/toolkit'
import { combineReducers } from 'redux'
import userSlice from '../slices/user'
import authSlice from '../slices/auth'
import matchSlice from '../slices/match'
import { persistReducer } from 'redux-persist';
import AsyncStorage from '@react-native-async-storage/async-storage';

const persistConfig = {
  key:'root',
  storage:AsyncStorage,
  blacklist: ['userMatch']
}

const rootReducer = combineReducers({
  userMain: userSlice,
  userAuth: authSlice,
  userMatch: matchSlice
})

const persistedReducer = persistReducer(persistConfig, rootReducer);

export const store = configureStore({
    reducer: persistedReducer,
    middleware: getDefaultMiddleware => getDefaultMiddleware({
      serializableCheck: false
    })
})

screens/HomeScreen.js

import React, {useEffect, useState} from 'react';
import {useSelector, useDispatch} from 'react-redux';
import { selectToken, setSignOut } from '../../redux/slices/user';
import match, { selectMatchData } from '../../redux/slices/match';

function HomeScreen({navigation}){
    const matchData = useSelector(selectMatchData);
    // CONSOLE LOGS UPDATED STATE VALUE
    console.log("1"+matchData);

    const loadUserData = () => {
	// CONSOLE LOGS INITIAL STATE VALUE
        console.log("2"+matchData);
        // fetch() ... fetching data ...
    };

    useEffect(() => {
        loadUserData();
    }, []); 
      

    return (         
        <View style={{flex:1}}> 
        </View> 
    );    
}

const styles = StyleSheet.create({
});

export default HomeScreen;

screens/SecondScreen.js

// ... React code ...
const dispatch = useDispatch();
let testData = {data: 12345}
<TouchableOpacity onPress={() => dispatch(setMatchData(testData))}
// ... React code ...

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
phryneascommented, Jul 20, 2022
    const loadUserData = React.useCallback(() => {
	// CONSOLE LOGS INITIAL STATE VALUE
        console.log("2"+matchData);
        // fetch() ... fetching data ...
    }, [matchData]);

    const onRefresh = React.useCallback(() => {
        setRefreshing(true);
        loadUserData();
        wait(1000).then(() => setRefreshing(false));
      }, [loadUserData]);    

assuming you have any good reason for all those useCallback calls in the first place. But if you use useCallback - or useEffect for that matter, your dependency arrays have to actually be filled. Enable the eslint rule for that and actually follow the rules of hooks or you get bugs like this.

0reactions
xerdnewcommented, Jul 20, 2022

@phryneas Thank you and now i completely understand with the example! I rewrote my code to remove the useCallback that caused the problem. Thank you so much once again!

Read more comments on GitHub >

github_iconTop Results From Across the Web

ReactJs state inside of nested function is not being ...
javascript - ReactJs state inside of nested function is not being updated, but it is updated outside(in fucntional component) - Stack Overflow. ...
Read more >
Why is it so difficult to modify a deeply nested state in React?
There are two main ways to deal with the problem of updating a deeply nested state. First is flattening your state to avoid...
Read more >
Rules of Hooks
Don't call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function, before any...
Read more >
Nested state
The state of an element is passed to a child component as a property. The child component gets and sets the deep nested...
Read more >
Common React Hooks Mistakes You Should Avoid
1. Changing the Hooks Invocation Order. Hooks should not be called within loops, conditions, or nested functions since conditionally executed Hooks can cause ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found