이번 글에서는 Rc-Tree 라이브러리를 사용하여 메신저 내 직원 조직도를 트리 구조로 시각화하는 방법을 단계별로 알아보겠습니다.
https://www.npmjs.com/package/rc-tree
1️⃣ Rc-Tree 개념과 사용 방법
`Rc-Tree`는 부모와 자식, 즉 폴더와 문서 같은 부모-자식 관계를 가진 데이터 구조를 시각화할 수 있는 React 트리 구성 요소입니다. 해당 라이브러리는 트리 구조를 쉽게 시각화하고 조작할 수 있는 기능을 제공합니다.
✔️ 기본 사용 방법
먼저 `rc-tree` 라이브러리를 설치합니다.
npm install rc-tree
이제 트리 구조를 만들기 위해 key, title, children 속성을 설정한 트리 데이터를 준비합니다. `key`는 각 노드의 고유 식별자, `title`은 노드의 이름, `children`은 자식 노드를 나타냅니다.
import Tree from "rc-tree"; // react-tree 라이브러리
import "rc-tree/assets/index.css"
const treeData = [ // 계층 구조의 트리 데이터
{
key: "1",
title: "folder 1",
children: [
{ key: "1-1", title: "file 1-1" },
{ key: "1-2", title: "file 1-2" },
{
key: "3",
title: "folder 3",
children: [
{ key: "3-1", title: "file 3-1" },
{ key: "3-2", title: "file 3-2" },
],
},
],
},
{
key: "2",
title: "folder 2",
children: [
{ key: "2-1", title: "file 2-1" },
{ key: "2-2", title: "file 2-2" },
],
},
];
<Tree treeData={treeData}></Tree>
위 예시에서는 폴더와 파일을 트리 구조로 나타냈습니다. 이 구조에서 Tree 컴포넌트에 `treeData`를 전달하여 트리 구조를 시각화할 수 있습니다.
2️⃣ Rc-Tree의 활용 - 메신저 조직도 구현
메신저에서 부서와 직원을 계층 구조로 시각화하여 조직도를 만들 수 있습니다. 부서는 상위 노드로, 직원은 하위 노드로 나타낼 수 있으며, 자식 노드가 없는 부서는 `isLeaf: false`로 설정할 수 있습니다.
✔️ 부서와 직원 관계 설정
아래는 부서와 직원의 관계를 트리 구조로 정의한 예시입니다. . 상위 노드에 부서 이름을 넣어주고 하위 노드에 부서의 직원 이름을 넣어주겠습니다. 트리 구조에서 children 배열을 사용하여 부서와 직원의 관계를 정의합니다. 그리고 `<Tree>` 컴포넌트 속성에 `treeData`를 넣어줍니다.
const treeData = [ // 트리 데이터
{
key: "1",
title: "Erpre",
children: [
{
key: "1-1",
title: "영업부",
children: [
{key: "1-1-1", title: "안유진"},
{key: "1-1-2", title: "김민주"}
]
},
{
key: "1-2",
title: "개발부",
children: [
{key: "1-2-1", title: "장원영"},
{key: "1-2-2", title: "최예나"},
{key: "1-2-3", title: "조유리"}
]
}
]
}
];
<Tree treeData={treeData}></Tree>
기본적인 트리 모양의 조직도가 만들어진 것을 확인할 수 있습니다. 이렇게 트리 구조로 조직도를 만들면 메신저에서 조직도 조회와 관리가 훨씬 편리해집니다. 만약 부서는 있는데 직원이 없는 경우는 어떻게 될까요?
{
key: "1-3",
title: "인사부",
isLeaf: false, // 자식 노드가 없는 경우 isLeaf: false 속성을 넣어준다
children: []
}
부서는 있지만 직원이 없는 경우에는 부서가 자식 노드로 인식되는 것을 확인할 수 있습니다. 이 경우 속성에 `isLeaf: false` 값을 넣어주면 해당 노드가 자식 노드가 아닌 부모 노드로 인식됩니다.
✔️ 체크 박스 기능 추가
메신저에서 여러 사람에게 쪽지나 채팅을 보내기 위해 체크박스 기능을 추가해 보겠습니다. Rc-Tree에서 지원하는 `checkable` 속성을 사용하여 체크박스를 활성화할 수 있습니다. 저는 메신저에 로그인 했을 때 모든 노드가 기본적으로 확장되기를 원하므로 `defaultExpandAll` 속성도 넣어 주었습니다. 체크박스가 활성화된 트리 구조를 만들 수 있으며, 체크된 항목은 `onCheck` 핸들러로 처리할 수 있습니다. 예를 들어, 선택된 직원 목록을 업데이트할 수 있습니다.
<Tree
treeData={treeData}
defaultExpandAll={true} // 모든 노드를 기본적으로 확장
checkable // 체크박스 설정
onCheck={handleCheck} // 체크 시 이벤트 (체크가 true인 노드의 title을 저장하는 이벤트함수)
/>
const handleCheck = (checkedKeys, { checkedNodes }) => {
const recipientNames = checkedNodes
.filter(node => !node.children)
.map(node => node.title);
setSelectedRecipients(recipientNames);
}
✔️ 아이콘 커스터마이징
다음으로는 투박한 폴더와 파일 아이콘을 좀 더 보기좋게 변경해보겠습니다. 아이콘 커스텀도 속성을 통해 해결할 수 있습니다. 트리 노드에 `icon` 속성을 추가해 원하는 이모티콘을 지정해보도록 하겠습니다.
{
key: "1",
title: "Erpre",
icon: <span className="parent-icon">🍎</span>,
children: [
{
key: "1-1",
title: "영업부",
icon: <span>🤝</span>,
children: [
{key: "1-1-1", title: "안유진"},
{key: "1-1-2", title: "김민주"}
]
},
// 생략
이렇게 원하는 아이콘을 지정하면 다음처럼 아이콘이 적용됩니다. 직원에는 추후 각자 지정한 메신저 온라인 상태를 표시할 것이므로 따로 아이콘을 지정하지 않고 그대로 두었습니다.
✔️ 서버에서 직원 데이터 가져오기
마지막으로, 서버에서 직원 데이터를 받아와서 트리 구조로 시각화하는 방법을 살펴보겠습니다. 데이터를 `API`로 받아와서 트리 구조로 변환한 후, `treeData`에 전달합니다.
useEffect(() => {
async function fetchData() {
try {
const response = await axios.get('/api/messengers/employeeList');
const employeeList = response.data;
const treeStructure = buildTreeData(employeeList);
setTreeData(treeStructure);
} catch (error) {
console.error('Failed to fetch employee data:', error);
}
}
fetchData();
}, []);
const buildTreeData = (data) => {
const departmentMap = {};
const tree = [
{
key: "0",
title: "Erpre",
icon: <span>🍎</span>,
children: []
}
];
// 각 직원 데이터를 부서별로 그룹화
data.forEach(employee => {
const departmentName = employee.departmentName;
const employeeNode = {
key: employee. employeeId,
title: employee.employeeName,
isLeaf: true
};
// 해당 부서가 이미 존재하는지 확인
if(!departmentMap[departmentName]) {
const departmentNode = {
key: employee.departmentId,
title: departmentName,
children: []
};
departmentMap[departmentName] = departmentNode;
tree[0].children.push(departmentNode);
}
departmentMap[departmentName].children.push(employeeNode);
});
return tree;
}
실제 데이터가 적용이 된 모습을 보실 수 있습니다.
3️⃣ 마무리
Rc-Tree는 다양한 계층적 데이터를 시각화하는 데 매우 유용합니다. 이 글에서는 메신저 조직도 구현 방법을 다루었으며, 체크박스 기능, 아이콘 변경, 서버 데이터 연동 등 다양한 커스터마이징 옵션을 사용했습니다. Rc-Tree 공식 문서를 참고하여 더 많은 기능을 활용해보세요!