
tree방식으로 목차를 작성하던 중
prntKey를 기준으로 depth(혹은 lvl)를 체크하여 각각의 depth 맞는 넘버링을 해주면 어떨까 싶어서 해당 사항 적용 및 방법을 작성하였다!
대분류(Chapter // lvl : 1)는 로마 숫자
중분류(Section // lvl : 2)는 아라비아 숫자
소분류는(Sub Section // lvl : 3)는 한글
순으로 진행 하였다.

최종
설계 구조는 아래와 같다
Edit.js
┣ numbering-helger.js
Edit에서는 여러 기능이 있지만 tree구조를 변경하면서 원래 state정보를 계속해서 변경하는 기능을 사용할 예정이다.
✔️ Edit.js
┣ numbering-helger.js
import update from 'immutability-helper';
const Edit = () => {
//리스트를 받을 state
const [mContent, setContent] = useState(init);
//rc-tree Api를 이용하여 tree값을 변경할 때 실행될 함수
//결과 값으로 sort된 tree값인 sortTree를 받는다.
const onChangeTree = (sortTree) => {
//mContent에서 직접 수정할 오브젝트
const { MLC_TOCLIST } = mContent;
//sortTree를 map으로 돌려서 각각의 요소를 비교하여 state값의 리스트에서 INDENT를 재정의 한다.
const nTocList = sortTree.map((s) => {
const nToc = MLC_TOCLIST[tabKey].find((f) => String(f.TOCID) === s.key);
return Object.assign(nToc, { PRNT_TOCID: s.prntId, INDENT: s.lvl });
});
// 재정의한 값을 immutability-helper 사용하여 변경한다.
setContent((prev) =>
update(prev, {
MLC_TOCLIST: {
[tabKey]: { $set: [...nTocList] },
},
})
);
};
//(생략)//
해당 사항을 통해 mContent가 변경 될 때 넘버링 값을 넣어주면 어떨까 해서 useEffect를 추가하였다. (적당한 위치에 넣어주자)
import { numberingData } from './panel/numbering-helper';
//(생략)//
useEffect(() => {
const list = numberingData({ mContent, tabKey });
setIndexList(list);
}, [mContent]);
이제 준비는 끝났다. util로 만들 numbering-helper.js를 만들고 설정해보자!
리스트의 INDENT값은 위의 Edit.js에서 sortTree 값의 lvl을 지정해주었다.
이제부터 INDENT값은 depth가 되시겠다.
INDENT 값을 체크 하여 리스트를 새로 만들었고 해당 list의 index순서에 따라서 Numbering을 하였다
예시
{ TOCID : 1 , INDENT : 1 , Numbering : 1 }
{ TOCID : 2 , INDENT : 1 , Numbering : 2 }
{ TOCID : 3 , INDENT : 1 , Numbering : 3 }
{ TOCID : 4 , INDENT : 1 , Numbering : 4 }
해당 코드는 아래와 같다.
Edit.js
┣ ✔️numbering-helper.js
export const numberingData = ({ mContent, tabKey }) => {
const { MLC_TOCLIST } = mContent;
const nTocList = MLC_TOCLIST[tabKey].map((s, index) => {
//INDENT가 1일 때 ROMAN_NUM key값을 출력한다.
let filterIndex = '';
if (s.INDENT === 1) {
//INDNET가 1인 값의 배열
const indentOneArray = MLC_TOCLIST[tabKey].filter((f) => f.INDENT === 1);
//각 배열 값의 index값(Numbering에서 가져올 key값)
filterIndex = indentOneArray.findIndex((f) => f.TOCID === s.TOCID);
return Object.assign(s, { Numbering: ROMAN_NUM[filterIndex + 1] });
//INDENT가 2일 때 일반 index값을 출력한다.
} else if (s.INDENT === 2) {
//INDNET가 2인 값의 배열
const indentOtherArray = MLC_TOCLIST[tabKey].filter((f) => f.PRNT_TOCID === s.PRNT_TOCID);
//각 배열 값의 index값(Numbering에서 가져올 key값)
filterIndex = indentOtherArray.findIndex((f) => f.TOCID === s.TOCID);
return Object.assign(s, { Numbering: filterIndex + 1 });
//INDENT가 3일 때 HANGLE_NUM key값을 출력한다.
} else {
//INDNET가 3인 값의 배열
const indentOtherArray = MLC_TOCLIST[tabKey].filter((f) => f.PRNT_TOCID === s.PRNT_TOCID);
//각 배열 값의 index값(Numbering에서 가져올 key값)
filterIndex = indentOtherArray.findIndex((f) => f.TOCID === s.TOCID);
return Object.assign(s, { Numbering: HANGLE_NUM[filterIndex + 1] });
}
});
잘 작동하였다. 그치만 여기서 문제가 발생
lvl값이 계속 늘어난다면 INDENT 값을 임시로 지정해준 1 2 그리고 else까지만 찾을 수 있어 매 케이스마다 계속 if문을 설정해주어야 한다... (이럴거면 코드 왜짬?)
그래서 재귀함수로 새롭게 작성하였다.
findChildrenList라는 함수를 만들어 계속해서 자기를 호출하게 하였다.
findChildrenList함수는 (PrntKey와 Numbering숫자)를 입력 받아 PrntKey의 자식 List인 childernList를 만들어 각 배열을 새롭게 만든 indexList에 삽입하도록 만들었다.
탈출 조건으로는 새롭게 만들어진 childrenList의 길이인 length 가 없다면 더이상의 자식은 없는 것으로 판단하여 해당 함수를 탈출 할 수 있게 작성하였다.
Edit.js
┣ ✔️numbering-helper.js
export const numberingData = ({ mContent, tabKey }) => {
const { MLC_TOCLIST } = mContent;
let indexList = {};
//자식 List를 찾을 함수 TOCID 받아서 indexList에 넣는다.
const findChildrenList = (TOCID) => {
//전체 리스트에서 TOCID와 PRNT_TOCID를 filter하여 자기 자식list를 찾는다
const childrenList = MLC_TOCLIST[tabKey].filter((f) => f.PRNT_TOCID === TOCID);
//찾은 리스트를 map으로 돌려 하나하나 Numbering을 해준다.
childrenList.map((item, index) => {
// indexList에 새로운 객체를 넣는다.
indexList = Object.assign(indexList, { [item.TOCID]: { Numbering: index + 1, TITLE: item.TITLE } });
//childrenList 각각의 배열의 TOCID값이 자식 List를 가졌는지 확인한다.
//자식이 없다면 [] 값을 넘겨 재귀함수를 탈출한다.
return MLC_TOCLIST[tabKey].filter((f) => f.PRNT_TOCID === item.TOCID).length > 0
? findChildrenList(item.TOCID)
: [];
});
};
findChildrenList('root');
return indexList;
};
결과
잘 들어간 것을 확인 할 수 있다.
근데 왜 sorting이 안되는 것 같지... 해당 사항은 차후 수정 하는 걸로...
아스키 코드 조합으로 하려 했지만 변수가 많아 어쩔 수 없이 각각 key value값으로 선언하였다...
export const HANGLE_NUM = {
1: '가',
2: '나',
3: '다',
4: '라',
5: '마',
6: '바',
7: '사',
8: '아',
9: '자',
10: '차',
11: '카',
12: '타',
13: '파',
14: '하',
15: '거',
16: '너',
17: '더',
18: '러',
19: '머',
20: '버',
21: '서',
22: '어',
23: '저',
24: '처',
25: '커',
26: '터',
27: '퍼',
28: '허',
29: '고',
30: '노',
31: '도',
32: '로',
33: '모',
34: '보',
35: '소',
36: '오',
37: '조',
38: '초',
39: '코',
40: '토',
41: '포',
42: '호',
};
export const ROMAN_NUM = {
1: 'Ⅰ',
2: 'Ⅱ',
3: 'Ⅲ',
4: 'Ⅳ',
5: 'Ⅴ',
6: 'Ⅵ',
7: 'Ⅶ',
8: 'Ⅷ',
9: 'Ⅸ',
10: 'Ⅹ',
11: 'ⅩⅠ',
12: 'ⅩⅡ',
13: 'ⅩⅢ',
14: 'ⅩⅣ',
15: 'ⅩⅤ',
16: 'ⅩⅥ',
17: 'ⅩⅦ',
18: 'ⅩⅧ',
19: 'ⅩⅨ',
20: 'ⅩⅩ',
21: 'ⅩⅩⅠ',
22: 'ⅩⅩⅡ',
23: 'ⅩⅩⅢ',
24: 'ⅩⅩⅣ',
25: 'ⅩⅩⅤ',
26: 'ⅩⅩⅥ',
27: 'ⅩⅩⅦ',
28: 'ⅩⅩⅧ',
29: 'ⅩⅩⅨ',
30: 'ⅩⅩⅩ',
31: 'ⅩⅩⅩⅠ',
32: 'ⅩⅩⅩⅡ',
33: 'ⅩⅩⅩⅢ',
34: 'ⅩⅩⅩⅣ',
35: 'ⅩⅩⅩⅤ',
36: 'ⅩⅩⅩⅥ',
37: 'ⅩⅩⅩⅦ',
38: 'ⅩⅩⅩⅧ',
39: 'ⅩⅩⅩⅨ',
40: 'ⅩⅩⅩⅩ',
41: 'ⅩⅩⅩⅩⅠ',
42: 'ⅩⅩⅩⅩⅡ',
};