리액트 state를 특정 조건에 따라서 필터링하여 갱신하고, 또 삭제하여 갱신하는 연습을 했다!
새롭게 알게 된 것
오늘 내용은 Advanced 요구사항 구현을 빙자한 삽질이 대부분이라 어떻게 정리를 해야 할지 감이 안 온다. 일단 오늘의 요구사항부터 정리해보자!
과제의 주요 요구사항은 C:사용자 입력데이터로 트윗 생성, R:모든 트윗 불러오기, D:버튼 클릭 시 트윗 삭제이다. 여기에 추가로 select와 option을 활용해 선택한 사용자가 쓴 글만 보이도록 하는 드롭다운 메뉴가 필요하다.
드롭다운 메뉴 만들기
먼저 드롭다운 메뉴를 만들기 위해서.. 처음에는 컴포넌트로 생각하고 접근했다. 이 부분까지 컴포넌트로 따로 분리하여 작성하는 것이 맞는지 잘 모르겠는데, 분리해서 작업을 한 결과 과정이 꽤 복잡했기 때문에 이렇게 작은 부분까지 컴포넌트로 분리할 필요는 없겠다는 생각이 들었다. (물론 상황에 따라 다르겠지만...)
아래 코드가 그 삽질의 결과물이다.(즉 일부만 작동된다..) Tweets 페이지 컴포넌트에서 호출되는 Selection 컴포넌트인데, props로 전체 트윗 목록과, 트윗목록(state) 갱신 함수, 그리고 이전 트윗 목록의 상태를 전달받는다. 나머지 동작들은 괜찮았는데(?) 안 되는 부분은 목록에서 초기 옵션을 클릭 시 전체 목록을 다시 렌더링 하는 부분이었다.
목록에서 초기 옵션을 선택했을 때 전체 목록을 표시하기 위해서 직전 트윗 목록을 가져와서 리렌더링을 했었다. 문제는 한 번 바뀐 상태는 괜찮지만 두 번 바뀌었을 때는 직전의 state도 이미 바뀐 값이기 때문에 변경이 적용된다는 것이다. useEffect와 useRef를 활용해 직전 상태를 만들어준 것은 좋았지만, 그런 부분을 생각하지 못했다.
이 모든 문제가 기존 tweet 목록과 filtered 된 tweet 목록을 별도의 state로 구분했어야하는데 그러지 않았기 때문에 생긴 일인 것 같다. 렌더링 하면서 기존 tweet 목록을 변경하니까 이전 값이나 원래 목록으로 아무리 돌아가고 싶어도 돌아갈 곳이 없는 것이다 ㅜㅜ.
// Tweets 컴포넌트 내부의 일부 코드이다. 이전 상태 기억하는 부분
const prevTweets = usePrevious(tweets);
function usePrevious(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}
//...
//...상위 페이지 컴포넌트인 Tweets 내부에서 불러온다.
{/* select */}
<div className="tweet__selectUser">
<Selection renderTweets={renderTweets} tweets={tweets} prevTweets={prevTweets} />
</div>
코드가 길지만 어차피 작동하지 않기 때문에.. 삽질했던 시간이 아까워서라도 기록으로 남겨본다. 깊게 공부하진 못했지만 useEffect와 useRef 에 대해서 대략적으로나마 알고 활용해 볼 수 있어서 좋은 경험이었다.
컴포넌트로 별도로 분리하니, 상태 업데이트 함수도 props로 전달해주어야하고, 바뀐 상태를 적용하는 게 조금 복잡하다는 생각이 들어서, Tweets 페이지 컴포넌트 내에서 직접 입력하고 상태를 변경하는 방식으로 코드를 다시 작성했다.
한 가지 배운 점은, 사용자가 드롭다운 메뉴에서 이름을 선택했느냐 선택하지 않았느냐, 즉 필터링을 해서 보여주어야 되느냐 그렇지 않느냐도 state가 될 수 있다는 것이다. 처음에는 선택한 이름을 state로 만들어서 그것을 기준으로 필터링한 새 배열을 만들어서 뿌려주었는데, 이런 접근도 가능하다는 것을 새롭게 알게 되었다. 아래는 코드의 일부.
추가적으로 트윗 삭제 기능은 아직 구현을 못했다 ㅜ. 레퍼런스가 있긴 하지만 조금 복잡하기도 하고, 다른 예제를 활용해서 만들면서 연습하려고 한다.
SUMMARY
잘한 점
오전에 알고리즘 문제 풀고, 타입스크립트 공부하고, 블로깅 한 것!
보완할 점
지금까지 배운 리액트 state, props 개념을 활용해서 간단한 todo 앱을 만들면서 복습하면 좋을 것 같다! 이번 주 주말까지 만들고 결과물 블로그에 업로드해보기.
느낀 점
오늘 어려웠던 점은 어떤 부분을 state로 등록해야할지 감이 잘 오지 않는 것이었다. 변하는 모든 부분이 state는 아닐 것이고, 또 어떤 관점으로 state를 바라보느냐에 따라서 코드의 방향이 바뀐다고 생각하니까 좀 더 신중하게 생각하고 접근해야겠다고 느꼈다.
페어님이 앞부분 챌린지를 미리 끝내고 오셔서 오늘은 거의 따로 진행을 했다. 나도 지금까진 과제를 미리 해오는 부분에 있어서 별 생각이 없었던 것 같은데, 그래도 같이 하는 것에 의미가 있다고 있는 것 같다. 앞으로는 페어를 좀 더 배려하려고 노력해야 되겠다는 생각이 들었다...!
재미가 있으면서도, 더 많이 빨리 배우려면 이것을 왜 이렇게 써야되는지 '왜????' 라는 의문을 늘 품고 공부해야 하는 것 같다.