Neo
Neo

Reputation: 4760

Should I update state in another state update, should i or shouldn't i?

I have 2 states, one is set from API response and other on when API response changes a particular threshold and I set it and clear it after a timeout, I use a hook to achieve the same.

So I want to know which is a better approach,

const [data, setData] = useState();
const [thresholdChanged, setThresholdChanged] = useState();
// I clear thresholdChanged message after 5 seconds
useEffect(() => {
  if(thresholdChanged !== undefined) {
    const timeout = setTimeout(() => setThresholdChanged(undefined), TIMEOUT)
    return () => clearTimeout(timeout);
  }
  return undefined;
}, [thresholdChanged])

Now setting the data I have 2 options First one will never recreate the update method but calls another setter inside the first setter, is it valid pattern?

const update = useCallback((newData) => {
   setData((currentData) => {
     if(currentData < SOME_VALUE && newData > SOME_VALUE) {
       setThresholdChanged(true)
     }
     return newData;
   })
}, [])

or should I go with the second one which will recreate the method every time the data gets updated

const update = useCallback((newData) => {
   if(data < SOME_VALUE && newData > SOME_VALUE) {
       setThresholdChanged(true)
   }
   setData(newData)
}, [data])

Which one is a better approach and why?

NOTE: Code has been simplified for asking the question.

Upvotes: 0

Views: 69

Answers (1)

cbdeveloper
cbdeveloper

Reputation: 31375

You should go with option #1 for two reasons:

  • It's good practice to access the currentState (I usually call it prevState) using the setState function. It ensures that you'll be reading a fresh value from state.

  • Since it will not be recreated on every data change, you'll be able to use React.memo() on components that receive the update method as props

const update = useCallback((newData) => {
   setData((currentData) => {
     if(currentData < SOME_VALUE && newData > SOME_VALUE) {
       setThresholdChanged(true)
     }
     return newData;
   })
}, [])

Upvotes: 2

Related Questions