4

Please, See this - https://codesandbox.io/s/morning-grass-z8qrq

https://codesandbox.io/s/blue-flower-wl92u

** the second click, third, fourth, fifth click - menuOpen is true, then again click false - behaves as expected**

let [menuOpen, setMenuOpen] = useState(false);

<div
    onClick={() => {
    // setMenuOpen(true);

    setMenuOpen(!menuOpen); // I's not updated in the First time.

    console.log(menuOpen); // First time: false // not updating
>
 .......// some code
</div>

Please give me, some answers. I have been trying to solve this problem for Two days. I just can't solve it.

5 Answers5

2

Try this:

export default function App() {
  const [menuOpen, setMenuOpen] = useState(false);
  return (
    <>
      <button onClick={() => setMenuOpen(!menuOpen)}>Click</button>
      Is menu Open: { menuOpen ? "True": "False"}
    </>
  );
}

Example demo can be found here.

Shahnawaz Hossan
  • 2,695
  • 2
  • 13
  • 24
  • Not async that's the problem, it is stale closure. The state setter is async but does not return a promise so that code doesn't work and even if it did you still logging a stale closure. – HMR Jun 28 '20 at 11:36
  • You know what: See this: https://codesandbox.io/s/blue-flower-wl92u – Fahmida Mashura Jun 28 '20 at 12:22
  • @FahmidaMashura, Isn't it okay in your case? I am seeing the correct output. That is toggling between true and false. – Shahnawaz Hossan Jun 28 '20 at 12:23
  • See this thing again(I updated): codesandbox.io/s/blue-flower-wl92u – Fahmida Mashura Jun 28 '20 at 12:31
  • move all your conditional function calls inside a `useEffect` with `menuOpen` as a dep. When your `onClick` callback function is created, it holds - and keeps - the value of `menuOpen` until a new function is created. – hotpink Jun 28 '20 at 12:39
  • @FahmidaMashura, got it. I think you want 2nd-5th click as true i.e menuOpen true and then false and then true respectively? Not being toggled, Right? – Shahnawaz Hossan Jun 28 '20 at 12:51
  • If you would like to implement that please see my demo again, I've updated my sandbox's code. Let me know whether you want this or not. – Shahnawaz Hossan Jun 28 '20 at 13:05
  • Thanks for your concern. It's not working. now the toggle is not working. you can see the code: https://codesandbox.io/s/trusting-leftpad-u8jow – Fahmida Mashura Jun 28 '20 at 14:36
  • My expectation or wanted: First is True. then toggle. like First 'true' than 'false' than 'true' than 'false'...so on. – Fahmida Mashura Jun 28 '20 at 14:43
  • @FahmidaMashura, updated the code. Please check [the demo](https://codesandbox.io/s/silly-frost-dure4) – Shahnawaz Hossan Jun 28 '20 at 14:57
  • when I render the page or refresh the page for the first time. then click it - it's true. 2nd time clicked it's true again. it should be false. It should be toggle. -- like First 'true' than 'false' than 'true' than 'false'...so on – Fahmida Mashura Jun 28 '20 at 15:26
  • Please, Update this: https://codesandbox.io/s/exciting-meninsky-5fnpf - see the console.log. – Fahmida Mashura Jun 28 '20 at 15:41
  • I did this because you said so. Ok if the toggling behavior was working before. [Updated](https://codesandbox.io/s/silly-frost-dure4), and please clear properly that what do you actually want. Thanks. – Shahnawaz Hossan Jun 28 '20 at 16:01
0

useState create queues for React core to update the state object of a React component. So the process to update React state is asynchronous for performance reasons. That's why changes don't feel immediate.

iamwebkalakaar
  • 358
  • 1
  • 9
0

Give this a try

setMenuOpen(prevMenuOpenState => !prevMenuOpenState);

or

<div
    onClick={() => setMenuOpen(!menuOpen)}
>
Kalhan.Toress
  • 21,683
  • 8
  • 68
  • 92
0

I had even this problem in my code. My scenario is as follows: Its hotel detail page. There is horizontal tab menu of room types. If a hotel has more than 3 types of room, then there is show room button. I am using React Functional components in through the code. hotel detail basic page and room section page are different components created. values are passed to room section components through props.

My problem: When I click to room type further 3rd type, then show room value in function (setSelectedTab()) room component doesn't set at an instant. And hence as function moves further, it doesn't set document.getElementById(id) since show room had not been set. As function (setSelectedTab()) completes in first click it sets the show room to true, but selected tab doesn't set. I had to click 2nd time to set the tab.

solution: After a long try and error, I settle down to the following: I declare the function as async and made await the setshowRoom() value. This solved my complete problem.

async function setSelectedTab(e, data) {
firstScroll += 1;

data >= 2 && await setMenuOpen(true);
if (data >= 0) {
  .................
  const id = e.href;
  const anchor = document.getElementById(id);
  ..............
..............
}
}

and in room component: showRoom, setshowRoom in useState and calling the setSelectedTab() using props. This solves problem of single click

Drawback: I found delay of 1 second to set this tab.

If anyone have better solution than this without making async await, then please post here. Thanks.

UdayanBKamble
  • 99
  • 1
  • 7
-1

The Answer is just refactoring the code into class Component without using hooks useState. Using state and setState to update. The Problem will solve.

But If I use useState hooks the problem remains the same Whatever I do with the code.