1

Context

I have a ContextProvider around my components. To this ContextProvider I connected a useState hook. In one of my components I want to set the value of the useState hook. If the value is the same value of the current state, then there is no delay. if the value is a new value compared to the current state, then there is a 2second delay.
As weird as my statement sounds, these stack questions have the same behavior:

What I found out by debugging

  • The delay is not caused by the sum (adding 1 to the previous value of the usestate), because setting a random value (for example the current datetime) will cause a 2sec delay as well
  • removing useCallback has no effect
  • rerenders of my own components are not causing the 2sec delay, because no components are using the context (and thus have no reason to rerender).
  • using useMemo to save the usestate variables has no effect on the delay

Project configurations

React-native:0.70.6

Code

(especially notice the last two components)

Contextprovider:

import React from 'react';

type CurrentEntryContextType = {
  answersBeingSaved: number;
  setAnswersBeingSaved: (count: number) => void;
};

export const CurrentEntryContext = React.createContext<CurrentEntryContextType>({
  answersBeingSaved: 5,
  setAnswersBeingSaved: () => {},
});

Main:

function App() {
  const [answersBeingSaved, setAnswersBeingSaved] = useState<number>(5);
  const currentEntryContext = useMemo(() => {
    return {
      answersBeingSaved: answersBeingSaved,
      setAnswersBeingSaved: setAnswersBeingSaved,
    };
  }, [answersBeingSaved]);
  return (
    <>
      <CurrentEntryContext.Provider value={currentEntryContext}>
              <MainNavigationBar />
      </CurrentEntryContext.Provider>
    </>
  );
}

Component that changes the context with 2s delay (calling the acknowledge is what's causing the delay):

function RandomComponent() {
  const currentEntryContext = useContext(CurrentEntryContext);
  
  const acknowledgeAnswerBeingSaved = useCallback(() => {
    currentEntryContext.setAnswersBeingSaved(
      currentEntryContext.answersBeingSaved + 3
    );
  }, [currentEntryContext]);
  return <></>;
}

Component that changes the context without 2s delay (this is just to demonstrate that the issue only occurs when the useState is set to a different value each time):

function RandomComponent() {
  const currentEntryContext = useContext(CurrentEntryContext);
  
  const acknowledgeAnswerBeingSaved = useCallback(() => {
    const redundantVariable = currentEntryContext.answersBeingSaved + 3;
    currentEntryContext.setAnswersBeingSaved(
      5
    );
  }, [currentEntryContext]);
  return <></>;
}
bieboebap
  • 320
  • 3
  • 18
  • 1
    what is `lastUpdated` and when/how do you update it ? – Gabriele Petrioli Dec 23 '22 at 01:25
  • 1
    Is the closing tag `CurrentEntryUpdatedContext.Provider` a typo? – Randy Casburn Dec 23 '22 at 01:44
  • I changed some names to make it more readable. There were 2 useState variables before (one of which lastUpdated), I removed it to make it less complicated. – bieboebap Dec 23 '22 at 02:01
  • In the example **without 2s delay**, memoization works to prevent re-rendering because `answersBeingSaved` only changes once (to `5`), and then remains the same. Since that value never changes there is no more re-rending - thus no delay. In the example that causes the 2s delay, the memoized value from the context changes and causes re-renders. You should be able to see this by profiling the app and watching `currentEntryContext` value change repeatedly. – Randy Casburn Dec 23 '22 at 16:11
  • I believe (one) fix would be to move the context accessor & variable assignment of `redundantVariable` outside the `useCallback()`. Then, only use `redundantVariable` inside the `useCallback()` hook with the `setAnswersBeingSaved()` setter. – Randy Casburn Dec 23 '22 at 16:20
  • @RandyCasburn the code part from "Component that changes the context without 2s delay" was just to show that the sum is not what is causing the delay, and that the delay is caused by a changing the useState to a different value. As mentioned in "What I found out by debugging", removing useCallback does not make a difference regarding the delay – bieboebap Dec 23 '22 at 18:31
  • Alright - put up a stackblitz that demonstrates your issue. – Randy Casburn Dec 23 '22 at 19:18

0 Answers0