skip to Main Content

I am trying to lean react by solving a problem in react. Providing the react code challenge below. I am not seeing any error in console. But my normal click event printing.Undo operation not working. Is it good to use spread operators or do I need to use something else to improve performance

I googled but still no luck, not sure how to solve it. Providing my code below and stackblitz. Can you guys help me.

https://stackblitz.com/edit/stackblitz-starters-gxje5c?description=React%20%20%20TypeScript%20starter%20project&file=src%2FApp.tsx,src%2Fstyle.css&title=React%20Starter

import { FC, useState } from 'react';

import './style.css';

type TPoint = {
  x: number;
  y: number;
};

export const App: FC<{ name: string }> = ({ name }) => {
  const [points, setPoints] = useState<TPoint[]>([]);

  function handlePlaceCircle(e: React.MouseEvent<HTMLDivElement>) {
    console.log(e);
    const { clientX, clientY } = e; // object destructuring
    setPoints([
      ...points,
      {
        x: clientX,
        y: clientY,
      },
    ]); // shallow refrence spread
  }
  function handleUndo() {
    //setPoints([...points.]);// grab only first set of elements and exclude last one
    const newPoints = [...points];
    newPoints.pop(); // this is through mutation
    setPoints(newPoints);
  }

  return (
    <>
      <div className="circleApp" onClick={handlePlaceCircle}>
        <button onClick={handleUndo}>Undo</button>
        {points.map((point) => (
          <div
            className="point"
            style={{
              left: point.x - 5 + 'px',
              top: point.y - 5 + 'px',
            }}
          >
            o
          </div>
        ))}
        <h1>Hello {name}!</h1>
        <p>Start editing to see some magic happen :)</p>
      </div>
    </>
  );
};

https://www.youtube.com/watch?v=A0BmLYHLPZs&list=PL6x5Q-Sj_Bla3_wMqhETxMBjFml0XJNPI&index=4

2

Answers


  1. Your logic for updating state seems to be working fine. The issue seems to be that your button logic is ignored because handlePlaceCircle is being called instead of handleUndo.

    You could call event.stopPropagation() to ensure handlePlaceCircle isn’t called when you click your button like so:

    <button
      onClick={(event) => {
        event.stopPropagation();
        handleUndo();
      }}
     >
    

    Or you could simply move your button outside of your div which has the handlePlaceCircle onClick handler.

    <>
      <button
        onClick={handleUndo}
      >
        Undo
      </button>
      <div className="circleApp" onClick={handlePlaceCircle}>
       {/* Other Logic... */}
      </div>
    </>
    
    Login or Signup to reply.
  2. handleUndo is fine, but the event is bubbling, so your handler for clicks is catching it. Stopping propagation will solve the issue.

    function handleUndo(e: SyntheticEvent) {
        e.stopPropagation();
        const newPoints = [...points];
        newPoints.pop();
        setPoints(newPoints);
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search