Akshay kharade
Akshay kharade

Reputation: 53

Is there a synchronous alternative of setState() in Reactjs functional components

I know how to do this in class components but when i use same code in functional component i get an error. This is what i want -

this.setState({cnt:this.state.cnt+1})
alert(this.state.cnt);

now i want the alert to show count as 1 . How we do it in class component -

this.setState({cnt:this.state.cnt+1}, () => alert(this.state.cnt));

But when i do same in functional component like this

const[count, setCount] = useState(0);
setCount(count+1, () => alert(count));

I get an error - "expected no of arguments - 1".

Upvotes: 4

Views: 2245

Answers (2)

Drew Reese
Drew Reese

Reputation: 202751

The pattern here is to also use a useEffect hook with a dependency array of the state value you want to alert on. The effect hook runs once per render when state updates, and the dependency array helps filter when the effect actually triggers, in this case when count updates.

const [count, setCount] = useState(0);

useEffect(() => {
  alert('count updated!);
}, [count]);

Upvotes: 3

Shubham Khatri
Shubham Khatri

Reputation: 281686

State updater with react-hooks doesn't provide a callback. You need to use useEffect to achieve the same behavior. Also since you would want the useEffect to run only on update you can disable its initial execution with the help of a useRef

setCount(prev => prev+1);
...
const initialRender = useRef(true);
useEffect(() => {
   if(!initialRender.current) {
     alert(count);
   } else {
     initialRender.current = false;
   }
}, [count]);

In some cases you may not want the useEffect to trigger whenever count is updated but only when count is updated from a special function. In such cases you can make use of useRef

const runEffect = useRef(false);
const initialRender = useRef(true);
useEffect(() => {
   if(!initialRender.current) {
     // This will only be executed when you toggle ref

     alert(count);
   } else {
     initialRender.current = false;
   }
}, [runEffect.current]);
// adding ref as a dependency is fine here since we know that a re-render will be triggered by setCount


someFunction = () => {
   setCount(prev => prev + 1);
   runEffect.current = !runEffect.current;
}

Upvotes: 3

Related Questions