Zergoholic
Zergoholic

Reputation: 101

setState callback method equivalent for useState hook

I'm looking for running some code after I set a new state via the "useState" hook. The only method I found tho was using "useEffect". But when i understand correctly, that would mean that code would run every time when I change the state. What if I have something like:

function example(props){
   const [example,setExample]=useState("")
   return[
      <div>{example}</div>,
      <Button onClick={()=>{setExample("Exampletext")}}>Set Text to Exampletext</Button>,
      <Button onClick={()=>{setExample("Exampletext",
            ()=>{
                   sleep(5000);//pseudo Code for "wait 5 seconds"
                   setExample("")}
             )}}>
       Set Text to Exampletext and back</Button>
   ]
}

(how I would write it if useState had a callback)
In this example, I can't use useEffect, since it would make both buttons behave the same if I'm not mistaken.

Edit:
I thought a general Example would suffice, but since there seems to be a solution to the example that doesn't apply to my problem, let me explain my case:

const [abortController, setAbortController] = React.useState(new Abortcontroller());

    const handleGetDetail = () => {
        setIsLoading(true);
        setIsError(false);
        abortController.abort();
        setAbortController(new AbortController());
        axios
            .get(`../../api/rest/${parameters.endpoint}/${parameters.pk}/`, {
                signal: abortController.signal,
                headers: { Accept: "application/json" },
            })
            .then((results) => {
                setFormData(results.data);
                setIsLoading(false);
            })
            .catch((error) => {
                if (error.name !== "CanceledError") {
                    console.log(error);
                    setIsError(true);
                    setIsLoading(false);
                }
            });
    };

The axios request starts before a new AbortController is initialized, so it will start with an already aborted signal and won't work at all. And i can't use useEffect , cause i am reusing the same abort controller for all requests of that component (there is an analoge method for post and patch ....).
The point of that code should be, to cancel the last request, if the user sends a second one before the first one is finished.

Upvotes: 0

Views: 268

Answers (1)

Nick Vu
Nick Vu

Reputation: 15520

Unfortunately, useState does not have a callback like setState of the class-based component.

But we still can use setTimeout for waiting time which will help you to delay the 2nd setState with a pre-defined time period.

function example(props) {
  const [example, setExample] = useState("");
  return [
    <div>{example}</div>,
    <Button
      onClick={() => {
        setExample("Exampletext");
      }}
    >
      Set Text to Exampletext
    </Button>,
    <Button
      onClick={() => {
        setExample("Exampletext");
        setTimeout(() => {
          setExample("");
        }, 5000); //will be triggered after 5 seconds
      }}
    >
      Set Text to Exampletext and back
    </Button>,
  ];
}

Upvotes: 1

Related Questions