let data; // (1) 앞으로 사용할 데이터. 변수 선언
const localStorageData = localStorage.getItem("discussionData");
if(localStorageData) { // 만약 localStorageData가 있으면 (= submit을 한 번 한 이후)
data = JSON.parse(localStorageData) // 로컬 스토리지에서 가져온 데이터로 할당
} else { // (2) localStorageData가 없으면 ( = 최초 렌더링일 경우)
data = agoraStatesDiscussions.slice(); // data는 agoraStatesDiscussions(원본 데이터)을 복사한 그대로. (QQQ: 처음 1번만 쓸 것이기 때문에 그냥 얕은 복사로? 주소값 같아도 상관없어서?)
}
form.addEventListener("submit", (event) => {
const newData = {
...
}
data.unshift(newData);
localStorage.setItem("discussionData", JSON.stringify(data));
while (ul.firstChild) {
ul.removeChild(ul.firstChild);
}
render(ul);
})
- JSON.Stringify( 배열 ): Local Storage에는 문자열만 저장할 수 있다. 배열을 문자열로 바꿔두자.
- localStorage.setItem( 키 값, 키에 할당할 문자열 ): 원하는 이름의 키를 생성하고 그 키에 문자열을 할당한다. 위 코드에서 키는 "discussion Data"
- localStorage.getItem( 키 값 ): 저장해둔 Local Storage의 키에 해당하는 값을 불러온다.
- JSON.Parse( 문자열 ): 불러온 값을 배열로 바꾸고 싶을 때 사용한다.
위 코드를 해석해보겠다.
1. data라는 변수를 선언한다.
2. localStorageData 라는 변수에 로컬 스토리지 키에 할당되어 있는 문자열을 불러온다. (submit 해야 값이 생김)
3. localStorageData의 값이 있으면(한 번이라도 submit을 한 적이 있다면) data에 localStorageData를 배열화해서 집어넣는다.
4. localStorageData의 값이 없으면 data에 agoraStatesDiscussions 배열을 얕은 복사해서 집어넣는다.
form.addEventListener 함수
1. 새로운 객체 newData를 선언한다. (게시될 글의 여러가지 정보가 들어있음)
2. data에 newData를 unshift한다. (제일 위에 추가될 수 있도록)
3. data에 unshift됐다고 HTML에 뜨는 게 아니다. 배열 요소만 추가됐을 뿐. 우리는 로컬스토리지에 이 바뀐 배열을 집어넣어야 한다. 어떻게? setItem을 사용해서.
4. ul의 모든 요소를 지운다.
5. 모든 요소를 다시 render
const renderContent = (page) => {
while (contents.hasChildNodes()) {
contents.removeChild(contents.lastChild);
}
for (let id = (page - 1) * maxContent + 1; id <= page * maxContent && id <= numOfContent; id++) {
contents.append(convertToDiscussion(data[id - 1])) // 여기서 싹다 지우고 새로 입력될 때 agoraStatesDiscussions 거를 불러와서 리셋되던 문제가 있었음.
}
}
const renderContent = (page) => {
while (contents.hasChildNodes()) {
contents.removeChild(contents.lastChild);
}
for (let id = (page - 1) * maxContent; id < page * maxContent && id < numOfContent; id++) {
contents.append(convertToDiscussion(data[id])) // 여기서 싹다 지우고 새로 입력될 때 agoraStatesDiscussions 거를 불러와서 리셋되던 문제가 있었음.
}
}
분명히 로컬스토리지에는 들어있는데 새로고침하면 게시글이 사라지는 문제 발생
페이지네이션을 할 때 글 한 번 싹 지우는 과정이 또 있었는데(renderContent 함수 안에서),
그 과정에서 불변하는 agoraStatesDiscussions 데이터를 불러와서 추가해줬기 때문에
새로고침하면 자꾸 내가 썼던 게 지워지는 문제가 발생
그 부분을 data로 바꿔주니 깔끔하게 해결됨(뭔가 새로 추가해야할 때는 무조건 최신화를 해줘야 한다)
submit을 하면 마지막 게시글이 사라지는 문제 발생
페이지네이션을 할 때 for문을 돌린다. 게시글을 10개씩 끊어서 한 페이지에 들어갈 수 있도록 하기 위해.
그 때 id < numOfContent 라는 조건을 만난다.
apppend 횟수가 게시글 개수를 초과할 수는 없기 때문에..
numOfContent라는 변수에는 data.length가 할당되어 있었다.
data가 바뀌어도 기존에 할당되어 있는 값은 바뀌지 않는다. 최신화를 해줘야 한다.
numOfContent 변수 선언했던 걸 없애버리고 numOfcontent가 들어갔던 자리에 data.length 를 넣어주면 된다.
아래는 수정 전 코드다. 어떻게 바꾸면 될지 상상해보자.
const numOfContent = data.length;
const renderContent = (page) => {
while (contents.hasChildNodes()) {
contents.removeChild(contents.lastChild);
}
for (let id = (page - 1) * maxContent; id < page * maxContent && id < numOfContent; id++) {
contents.append(convertToDiscussion(data[id]))
}
}
// 갓상은!!!! numOfContent는 위에서 data.length를 할당받은 상태이다.
// 근데 data가 추가되어도 기존에 받아놨던 길이는 변하지 않으니 하나씩 지워질 수 밖에!!!
// numOfContent 선언식을 지우고 함수 안의 numOfContent 를 data.length로 바꿔서 그때그때 최신화
submit 을 하면 첫 화면에 모든 게시글이 보이는 문제 발생
이것도 마찬가지로 최신화를 안 해줘서 발생한 문제다. 게시글이 추가되면 페이지네이션을 다시 해줘야 한다.
submit 눌렀을 때 실행되는 함수 맨 끝에 renderContentAndButton(page); 한번 호출하면 해결.
혼자 하루종일 고민해서 해결 안되던게
스터디원분들하고 함께 고민하니 20분만에 풀렸다. 이것이 집단지성인가??
2023년 1월 10일 21시 33분 다시 문제 발생
게시글 50개가 꽉찬 후 추가해도 6페이지가 안 생김
const maxPage = Math.ceil(data.length / maxContent);
const renderButton = (page) => {
// 버튼 리스트 초기화
while (buttons.hasChildNodes()) {
buttons.removeChild(buttons.lastChild);
}
// 화면에 최대 5개의 페이지 버튼 생성
for (let id = page; id < page + maxButton && id <= maxPage; id++) {
buttons.appendChild(makeButton(id));
}
// 첫 버튼 활성화(class="active")
buttons.children[0].classList.add("active");
buttons.prepend(prev);
console.log(buttons.innerHTML);
buttons.append(next);
// 이전, 다음 페이지 버튼이 필요한지 체크
if (page - maxButton < 1) buttons.removeChild(prev);
if (page + maxButton > maxPage) buttons.removeChild(next);
};
// 위와 마찬가지로 maxPage 속 data.length는 게시글이 추가되어도 변하지 않는다.
// 그러므로 변수 maxPage 선언식을 빼버리고
// 함수 안에 있는 maxPage를 Math.ceil(data.length / maxContent)로 바꿔준다. (그때 그때 최신화)
위의 문제와 완전히 동일하다 maxPage라는 변수에 할당된 값에는 data.length라는 값이 포함되어 있는데, 이 값은 data의 배열이 바뀐다 해도 변하지 않는다. 그러므로 변수 maxPage 선언식을 빼버리고 함수 안에 있는 maxPage를 Math.ceil(data.length / maxContent) 로 바꾼다. 그러면 함수를 돌 때마다 data를 새로 불러오기 때문에 최신화가 바로바로 된다.
'부트캠프 > TIL' 카테고리의 다른 글
코드스테이츠 프론트엔드 부트캠프 day 21 - 고차함수 (2) | 2023.01.13 |
---|---|
Section 1 회고 (0) | 2023.01.11 |
코드스테이츠 프론트엔드 부트캠프 Day 18 - Coz' Mini Hackathon (4) 페이지네이션 (0) | 2023.01.09 |
코드스테이츠 프론트엔드 부트캠프 Day 18 - Coz' Mini Hackathon (3) 데이터 불러오기 (0) | 2023.01.09 |
코드스테이츠 프론트엔드 부트캠프 Day 18 - Coz' Mini Hackathon (2) 버튼 토글 (0) | 2023.01.09 |