comment 영역 구현
해커뉴스 사이트의 댓글창은 대댓글을 달 수 있게 되어있다.
한 게시글에 댓글은 여러 개가 달릴 수 있고, 또 하나의 댓글에 여러개의 댓글이 다시 달릴 수 있는 구조이다. 따라서 comment라는 값은 여러개의 데이터들을 한번에 담을 수 있는 배열로 전달된다.
이 댓글 값을 뿌려주기 위해서는 데이터의 깊이가 몇 단계까지 있는지를 확인해야하는데, 가장 상위에 있는 값을 살폈을 때 안에 존재하는 모든 깊이의 데이터들을 다 열어보지 않는 이상 사실상 알 수 있는 방법이 없다.
이것을 해결하기 위해 재귀호출을 사용한다. 재귀호출이란 하나의 함수에서 자기 자신을 다시 호출하는 것을 말한다.
댓글 같은 경우엔 각각의 글들을 표시해주는 방식이 똑같다. 이 말은 즉, 댓글이나 대댓글이나 처리하는 로직이나 코드가 같다는 뜻이다. 따라서 댓글을 표시하는 기능을 함수로 만들어준 후, 댓글 안에 대댓글이 있을 경우 만들어둔 댓글 함수를 자기 자신 내부에서 다시금 호출해가며 대댓글이 더이상 없을 때까지 반복해가며 처리하게끔 만들어 준다.
function makeComment(comments, called = 0) {
const commentString = [];
for(let i = 0; i < comments.length; i++) {
commentString.push(`
<div style="padding-left: ${called * 40}px;" class="mt-4">
<div class="text-gray-400">
<i class="fa fa-sort-up mr-2"></i>
<strong>${comments[i].user}</strong> ${comments[i].time_ago}
</div>
<p class="text-gray-700">${comments[i].content}</p>
</div>
`);
// 재귀호출
if (comments[i].comments.length > 0) {
commentString.push(makeComment(comments[i].comments, called + 1));
}
}
return commentString.join('');
}
상태추가
네트워크를 통해 가져온 데이터에다가 새로운 상태값을 하나 추가해서 관리하는 방법을 사용한다.
이 방법을 사용하는 이유는 목록을 표시할 때마다 네트워크에서 새로운 값을 매번 받아오는 것이 비효율적이기 때문이다.
이를 해결하기 위해서는 한번 받아온 데이터값들을 수정해서 상태로 들고있으면 된다.
const store = {
currentPage: 1,
feeds: [],
};
function newsFeed() {
let newsFeed = store.feeds;
const newsList = [];
...
if (newsFeed.length === 0) {
newsFeed = store.feeds = makeFeeds(getData(NEWS_URL));
}
...
}
읽은 상태를 처리하기 위해서는 별도의 속성이 하나 더 필요한데, 이를 추가하기 위한 별도의 함수를 하나 더 만들어준다. 이 함수에서는 가져온 목록 데이터들을 반복문으로 돌면서 read 속성을 추가해준다.
function makeFeeds(feeds) {
for (let i = 0; i < feeds.length; i++) {
feeds[i].read = false;
}
return feeds;
}
이후 글을 읽었을 때, 해당 게시글의 아이디가 일치하는 데이터를 찾아 read 값을 변경해주는 코드를 상세화면을 호출하는 함수에 추가해준다.
function newsDetail() {
const id = location.hash.substr(7);
const newsContent = getData(CONTENT_URL.replace('@id', id))
...
for(let i=0; i < store.feeds.length; i++) {
if (store.feeds[i].id === Number(id)) {
store.feeds[i].read = true;
break;
}
...
}