테스트용 데이터를 생성하는 화면을 만들었다. 그런데 데이터의 구조가 상당히 복잡했다. 리스트 안에 추가될 수 있는 객체가 두 종류였고 depth도 깊었다. 컴포넌트로 쪼개서 관리하다보니 하위 컴포넌트가 3개 정도 나왔는데 마지막 컴포넌트에서 최상위 state를 조작할 때쯤엔 이게 맞나 싶을 정도였다.
// state 구조 예시
[
// 객체 종류1: 기간일 때
{
seq: 0,
byPeriod: {
day: 10,
amt: 100000,
startDt: "2024-08-10"
}},
// 객체 종류2: 날짜일 때
{
seq: 1,
byDate: [
{
amt: 1000000,
date: "2024-08-10",
tempKey: "eljfeijjsl"
},
{
amt: 1000000,
date: "2024-08-11",
tempKey: "glajekjlkfj"
},
{
amt: 1000000,
date: "2024-08-12",
tempKey: "helkjslkjflj"
}}]
위 구조에서 날짜일 때 객체는 삭제, 수정 시 byDate 안에서 다시 객체를 조작해야 하기에 임시키를 추가해주었다.
그러니까, 특정 데이터를 수정하려면
1) 전체 데이터를 map을 돌려서 seq가 일치하는 객체를 찾고
2) 기간별일 경우엔 byPeriod, 날짜별일 경우엔 byDate 안으로 들어가서
3) 날짜별일 경우 다시 map을 돌려 tempKey가 일치하는 객체를 찾아서
4) 타켓 인자의 데이터를 업데이트해주면 된다!
5) 물론 이 과정에서 타겟이 아닌 객체들은 그대로 반환해주어야 한다.
(어 써놓고 보니 할 만 한데...?)
전역 상태관리로 풀어야 하는 건가 고민했는데 보다 근본적인 해결책이 있었다. state는 데이터 구조를 플랫하게 만드는 게 권장된다.
이번 작업에서 state 구조가 복잡해진 이유는 개발 초기엔 데이터 가공 과정을 줄이려고 api 전송 형식을 최대한 맞추려 했고 이후엔 컴포넌트 UI 구조를 그대로 따라갔기 때문이다.
api 전송 형식이나 UI에 관계 없이 state 데이터 구조를 완전히 독립적으로 관리하는 것이 핵심인 것 같다.
// 개선안
// 객체 종류1: 기간일 때
[{
seq: 0,
type: "byPeriod",
day: 10,
amt: 100000,
startDt: "2024-08-10"
},
// 객체 종류2: 날짜일 때
{
seq: 1,
type: "byDate",
"eljfeijjsl": {
amt: 1000000,
date: "2024-08-10",
},
"glajekjlkfj": {
amt: 1000000,
date: "2024-08-11",
},
"helkjslkjflj": {
amt: 1000000,
date: "2024-08-12",
}}]
구조가 1 depth 정도 줄어들었다. 이렇게 변경해보고 어떤지 확인해봐야겠다!