skip to Main Content

I’m facing an issue with a React component in my project where I have to click twice to correctly log the right-clicked variable during navigation. Here’s a breakdown of the problem and my code:

I have a React component that represents a course lesson navigation system. When I click on a lesson in the navigation menu, it should log the index of the clicked lesson and initiate certain actions. However, I’ve noticed that I need to click twice to get the correct index to be logged.

Inside the component, there’s a function named handleOtp which handles the logic for initiating video playback and setting up an OTP for video access. The problem seems to originate from this function.

Here’s a simplified outline of the handleOtp function:

const handleOtp = async () => {
  try {
    const lessonId = course.lessons[clicked]?.video?.id;

    // This is the problematic area
    const { data } = await axios.post("/api/videoOtp", {
      videoId: lessonId,
      username: user.username,
      ip,
    });

    if (!data.otp && !data.playbackInfo) {
      return toast.error("Video OTP Failed! Reload Page");
    }

    loadVideo({
      otp: data.otp,
      playbackInfo: data.playbackInfo,
      configuration: {
        autoplay: true,
      },
      container: container.current,
    });
  } catch (err) {
    console.error(err);
  }
};

As per my observations, the first click triggers the handleOtp function but with the wrong clicked index, resulting in unexpected behavior. The second click finally logs the correct clicked index and works as intended.

I’ve ensured that there are no asynchronous state updates that might be causing the issue. I suspect there might be a timing or state management problem that’s causing this behavior, but I’m struggling to pinpoint the exact cause.

I’m seeking assistance in understanding why this double-click behavior is occurring and how to ensure that the correct clicked index is logged on the first click. Any insights or suggestions would be greatly appreciated. Thank you!

My React Component :

<StudentRoute>
        <div className="row mt-2">
          <div className="lessons-menu">
            <Menu
              defaultSelectedKeys={[clicked]}
              inlineCollapsed={collapsed}
              style={{ height: "100%" }}
            >
              {course.lessons.map((lesson, index) => (
                <Item
                  onClick={async () => {
                    setClicked(index);
                    setIsLoading(true);
                    setSpin(true);
                    setCheckoutVisibility("none");
                    checkTransactionStatus(index);
                    setPaymentMethod("kiosk");
                    setKioskPhoneNumber("");
                    handleOtp();
                  }}
                  
                  key={index}
                  icon={<Avatar>{index + 1}</Avatar>}
                >

Tried console.log the clicked variable :

2

Answers


  1. It is because setState works asynchronously. You are setting clicked in OnClick event and after that calling handleOtp function. In this case state is not updated yet and you will have a wrong index for the first click.

    You just need to pass index to handleOtp as parameter. And there is no need for setClicked anymore.

    const handleOtp = async (index) => {}
    
    <StudentRoute>
        <div className="row mt-2">
          <div className="lessons-menu">
            <Menu
              defaultSelectedKeys={[clicked]}
              inlineCollapsed={collapsed}
              style={{ height: "100%" }}
            >
              {course.lessons.map((lesson, index) => (
                <Item
                  onClick={async () => {
                    setIsLoading(true);
                    setSpin(true);
                    setCheckoutVisibility("none");
                    checkTransactionStatus(index);
                    setPaymentMethod("kiosk");
                    setKioskPhoneNumber("");
                    handleOtp(index);
                  }}
                  
                  key={index}
                  icon={<Avatar>{index + 1}</Avatar>}
                />
              ))}
            <Menu/>
          </div>
        </div>
    <StudentRoute/>
    
    Login or Signup to reply.
  2. You are passing index as key prop. key is a special word in react and you should not pass your props using it because react doesn’t pass key as a prop automatically and you will receive undefined inside child component and experience some strange behaviours. Try passing index with another name such as keyName and see what happens.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search