Home > Software design >  Why does react show previous value onclick,
Why does react show previous value onclick,

Time:10-06

I have 3 array of objects that i am trying to console log. Whenever the array is changed(via a button click from a separate component) I simply want to log the array of objects associated with the clicked button.

But there's some delayed reaction going on

EXAMPLE:

  • Arr1 - 3objs -> associated with btn1
  • Arr2 - 6objs -> associated with btn2
  • Arr3 - 2objs -> associated with btn3

WHAT I AM EXPECTING:

  • when I click btn1 display array of 3objs
  • when I click btn2 display array 6objs
  • when I click btn3 display array 2objs

HOW IT IS ACTUALLY PERFORMING:

  • click btn1 -> [ ]
  • click btn2 -> display array of 3objs
  • click btn3 -> display array 6objs
  • click btn1 -> display array 2objs
  • click btn2 -> display array of 3objs

its always 1 behind what it should be.

CODE:

  // These variables are being passed in as props ->  
getKpiResolvedTix, 
getKpiCanceledTix,
getKpiClosedTix

const [newKpiTixArr, setNewKpiTixArr] = useState<any>([])

  const renderCsvData = () => {
    if (getKpiResolvedTix) {
      setNewKpiTixArr(getKpiResolvedTix)
    } else if (getKpiCanceledTix) {
      setNewKpiTixArr(getKpiCanceledTix)
    } else if (getKpiClosedTix) {
      setNewKpiTixArr(getKpiClosedTix)
    }
}

  useEffect(() => {
    renderCsvData()
    console.log(newKpiTixArr)
  }, [getKpiResolvedTix, getKpiCanceledTix, getKpiClosedTix])

CODE EXPLANATION:

//each of the 3 "get" variables are props. essentially
when a button is clicked the tickets are filtered
to show only those tickets. 

//essentially if you click the resolve button -> it will
display all tickets with a resolved status. behind
the scenes this is an array of ticket objects.
  getKpiResolvedTix,
  getKpiCanceledTix,
  getKpiClosedTix

CodePudding user response:

That's because useEffect is running your console.log() before updating the state which is newKpiTixArr.

to fix that you either place your console.log(newKpiTixArr) outside of a useEffect this way it will be logged each time the component re-renders. or if you want to log it only when it changes then add another useEffect that listens to changes only on newKpiTixArr state and place your console.log() inside it. like this below

useEffect(() => {
    console.log(newKpiTixArr)
}, [newKpiTixArr])

CodePudding user response:

The state change is effective only at the next rendering.

Please take a look at this answer for more details.

CodePudding user response:

try spreading the arrays when set state as showed bellow

const renderCsvData = () => {
    if (getKpiResolvedTix) {
      setNewKpiTixArr([...getKpiResolvedTix])
    } else if (getKpiCanceledTix) {
      setNewKpiTixArr([...getKpiCanceledTix])
    } else if (getKpiClosedTix) {
      setNewKpiTixArr([...getKpiClosedTix])
    }
}

  • Related