개발개발/LifeGraph_인생그래프

[인생 그래프] 클릭 데이터 전역상태로 관리하기

yelimu 2025. 2. 10. 16:44

클릭 입력을 마치면 "그래프 생성하기" 버튼을 눌러서 결과 페이지로 이동시킨다.

points 데이터를 기반으로 그래프로 보여줘야해서 zustand 를 이용해서 데이터를 전역 상태로 관리하려고 한다.

 

결과 페이지에서 이전 페이지로 이동했을때도 이전에 입력한 값이 남아있었으면 좋겠어서 전역상태로 관리하기로 했다.

("수정하러 가기")

"reset" 기능도 추가할 수 있게 되었다. 

 

store 에서 아래와 같이 정의했다. 

  • addPoint : 클릭한 점의 좌표를 배열에 추가
  • setTitle : 클릭 시에는 title을 ""으로 받기때문에 input에 입력한 값을 onChange함수 안에서 setTitle
  • resetPoint : 빈 배열로 리셋
import { create } from "zustand";

interface PointData {
  id: number;
  x: number;
  y: number;
  title: string;
}

interface GraphStore {
  points: PointData[];
  addPoint: (point: PointData) => void;
  setTitle: (id: number, title: string) => void;
  resetPoints: () => void;
}

export const useGraphStore = create<GraphStore>((set) => ({
  points: [],
  addPoint: (point) => set((state) => ({ points: [...state.points, point] })),
  setTitle: (id, title) =>
    set((state) => ({
      points: state.points.map((point) => (point.id === id ? { ...point, title } : point)),
    })),
  resetPoints: () => set({ points: [] }),
}));

 

Graph 컴포넌트 안에서 이전에 로컬 상태로 관리하던걸 대체해주었다. 

// Graph.tsx

const { points, addPoint, setTitle } = useGraphStore();

  const handleClick = (e: MouseEvent<HTMLDivElement>) => {
    const rect = e.currentTarget.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;
    addPoint({ id: Date.now(), x, y, title: "" }); // 클릭한 좌표 추가
  };


  const handleChange = (e: ChangeEvent<HTMLInputElement>, id: number) => {
    setTitle(id, e.target.value);
  };

return (
    <div className="graph-container" onClick={handleClick}>
      {points.map((point) => (
        <Point
          key={point.id}
          x={point.x}
          y={point.y}
          title={point.title}
          onChange={(e) => handleChange(e, point.id)}
          ref={inputRef}
        />
      ))}
      <div className="graph" id="graph-upper"></div>
      <div className="graph"></div>
    </div>
  );

이미지를 클릭하면 사이트로 이동합니다.