1

Using React Hooks I would like to change the text of my button when a user clicks it to say "Added" and then I would like to set it back to the original text "Add to Cart" after 1 second. I assume I would use setTimeout for this but am having trouble figuring out how to use it in this case.

I have this

  const [buttonText, setButtonText] = useState("Add To Cart");

and this so far.

  <button
    type="submit"
    onClick={() => setButtonText("Added")}
  >
    {buttonText}
  </button>
krichey15
  • 591
  • 6
  • 14

5 Answers5

2

Add the timeout inside useEffect, and pass buttonText as dependency, every time the buttonText is updated, the timeout will restore the default text value:

const text = "Add To Cart" 
const [buttonText, setButtonText] = useState(text);

 useEffect(()=> {
    const timer = setTimeout(()=> {
       setButtonText(text);
    }, 1000);
    return ()=> clearTimeout(timer);
 }, [buttonText])
 
 return (<button
    type="submit"
    onClick={() => setButtonText("Added")}
  >
    {buttonText}
  </button>)

Working example

lissettdm
  • 12,267
  • 1
  • 18
  • 39
  • Thank You! Yes This works great. Another question I is if am using useState elsewhere in the same component. Will this override the previous call of useState? – krichey15 Mar 20 '21 at 16:01
  • Do you mean call setButtonText(text) in other part of the component? – lissettdm Mar 20 '21 at 16:08
  • I am brand new to this React Hook business. haha. But I couldn't figure out how to use my current click handler to also change the word of the button so I thought I would use 2 (never tried it before) the first 1 adds things to the cart and uses useState the second would be this one. but adding this one breaks the first. – krichey15 Mar 20 '21 at 16:14
  • setButtonText("Added")} > – krichey15 Mar 20 '21 at 16:15
  • 1
    Yes, the second onClick will override the first one, but you can create a function to call both (handleAddToCart and setButtonText), ie: const handleClick = () => {handleAddToCart(); setButtonText("Added") }, then inside button: onClick={handleClick} – lissettdm Mar 20 '21 at 16:18
  • Haha have you ever gotten so far along in a topic you have forgot the basics...no just me then? Wow thanks for this. :) – krichey15 Mar 20 '21 at 16:28
0

In this way should work:

<button
   type="submit"
   onClick={() => {
   setButtonText("Added");
   setTimeout(() => {
     setButtonText("Add To Cart");
      }, 1000);
     }}
   >
    {buttonText}
 </button>

Here an example: https://codesandbox.io/s/react-hooks-change-text-of-button-on-click-and-then-back-again-qhbzv?file=/src/App.js

Girgetto
  • 1,010
  • 9
  • 19
0

Let's use useEffect:

useEffect(() => {
  const timeout = window.setTimeout(() => {
    setButtonText("Add To Cart")
  }, 1000)

  return () => window.clearTimeout(timeoutID )
}, [buttonText])
Bart Krakowski
  • 1,655
  • 2
  • 8
  • 25
  • The callback will trigger after each change of state. This way we will take care of clearing the timeout after the operation. – Bart Krakowski Mar 20 '21 at 15:24
  • @nullptr as the state keep the same value, it will not detect changes and this block will not be executed again. – lissettdm Mar 20 '21 at 15:41
0

Just change the onClick handler to this

onClick={
setButtonText("Added");
setTimeout(() => setButtonText("Add to Cart"), 1000)
}
nullptr
  • 3,701
  • 2
  • 16
  • 40
0

Here is a solution I made https://codesandbox.io/s/objective-kilby-nicm4?file=/src/App.js

I just used setTimeout to make it a 1 sec change after i got the update button title from the function.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Othman
  • 72
  • 10