개발개발/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>
);