I am learning react hooks, I have created below simple increment and decrement counter app. What I want is that whenever the user clicks on the Increment or Decrement Button it should show the value in the alert Box.
After writing useEffect
when the app launches I am getting an alert before clicking the Increment and Decrement Button.
One approach I know is that I can add the condition in useEffect
when the value of the counter is greater than zero(alert>0), but that's not what I am looking for, I want some generic solution.
Alert should call only when the user Clicks on Increment and Decrement Button and we should use hooks.
const Counter = () =>{
const [value, setValue]= useState(0)
useEffect(()=>{
displayAlert()
},[displayAlert])
function displayAlert(){
alert(value)
}
return(
<>
<p>Counter : {value}</p>
<input type="button" value="Increment" onClick={()=>setValue(value 1)}/>
<input type="button" value="Decrement" onClick={()=>setValue(value-1)}/>
</>
)
}
export default Counter
CodePudding user response:
Even if you put value
as a dependency for useEffect, it will show the alert the first time you load the page (when value
gets its initial value of 0). I propose creating a function that changes value
and displays the alert, and calling that from onClick
:
function changeAndDisplayValue(newValue){
setValue(newValue);
alert(newValue);
}
You call alert(newValue)
and not alert(value)
because setValue()
works asynchronously, so it may not yet have finished when alert
is called (therefore value
may still have the old value).
Then your buttons are like this:
<input type="button" value="Increment" onClick={()=>changeAndDisplayValue(value 1)}/>
<input type="button" value="Decrement" onClick={()=>changeAndDisplayValue(value-1)}/>
CodePudding user response:
There's react-use library that does provide a use "update" hook. https://github.com/streamich/react-use/blob/master/docs/useUpdateEffect.md
Check out their implementation:
- https://github.com/streamich/react-use/blob/master/src/useUpdateEffect.ts
- https://github.com/streamich/react-use/blob/master/src/useFirstMountState.ts
CodePudding user response:
Apart from conditional check in useEffect
there is no way to prevent first call of useEffect
. One other approach would be to have a separate useEffect
and a state which would hold the didMount
property. Initially didMount
would be false
and as soon as the useEffect
runs it would convert didMount
to true
. Then on your original useEffect
you would check if didMount
is true
, and only then call your function (alert)
CodePudding user response:
I believe MORÈ means this:
const Counter = () =>{
const [value, setValue]= useState(0)
useEffect(()=>{
displayAlert()
},[value])
function displayAlert(){
alert(value)
}
return(
<>
<p>Counter : {value}</p>
<input type="button" value="Increment" onClick={()=>setValue(value 1)}/>
<input type="button" value="Decrement" onClick={()=>setValue(value-1)}/>
</>
)
}
export default Counter