프라이D
프라이Develog(❁´◡`❁)
프라이D
전체 방문자
오늘
어제
  • ALL (378)
    • TDD, Cleancode with JavaScr.. (5)
    • 프로젝트 (32)
      • work (3)
      • 직접 만드는 기술 블로그 (2)
      • 데일리 옥션 (19)
      • 모락모락 (8)
    • Computer Science (1)
    • Algorithm & 자료구조 (94)
      • 알고리즘 w.JavaScript (53)
      • 자료구조 (5)
      • (인프런) 자바스크립트 알고리즘 문제풀이 (34)
    • JavaScript (45)
      • JavaScript (41)
      • 모던 자바스크립트 Deep Dive (4)
    • WEB (13)
    • 회고 (12)
    • TIL (109)
    • WIL (7)
    • Stacks (20)
      • React.js (6)
      • Next.js (1)
      • Redux (3)
      • Node.js (2)
      • GIT (2)
      • SAP (1)
    • 15일 메이킹 프로젝트 (15)
    • 이전 기록 (14)
    • ETC. (5)
    • ---------------2021 (6)
      • 내일배움단-웹개발 5주 (2)
      • 정보처리기사 (4)

블로그 메뉴

  • 홈
  • 태그
  • 미디어로그
  • 위치로그
  • 방명록

공지사항

인기 글

태그

  • 내일배움카드
  • 코딩프로젝트
  • 모던자바스크립트딥다이브
  • 자바스크립트알고리즘
  • 비트마스크
  • 국비지원
  • 2023 인프콘 후기
  • 자바스크립트비트마스크
  • vanilaJS
  • 스파르타코딩클럽
  • 알고리즘
  • 코드스테이츠
  • nomadcoder
  • Til
  • nomadcoders
  • JavaScript
  • 내일배움단
  • MySQL
  • 자바스크립트
  • 투포인터알고리즘

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
프라이D

프라이Develog(❁´◡`❁)

[Day 30] 2022-0803 : state 배열 데이터 필터링과 데이터 삭제
TIL

[Day 30] 2022-0803 : state 배열 데이터 필터링과 데이터 삭제

2022. 8. 3. 23:41

오늘 배운 것

  • 리액트 state를 특정 조건에 따라서 필터링하여 갱신하고, 또 삭제하여 갱신하는 연습을 했다!

새롭게 알게 된 것

  • 오늘 내용은 Advanced 요구사항 구현을 빙자한 삽질이 대부분이라 어떻게 정리를 해야 할지 감이 안 온다. 일단 오늘의 요구사항부터 정리해보자!
  • 과제의 주요 요구사항은 C:사용자 입력데이터로 트윗 생성, R:모든 트윗 불러오기, D:버튼 클릭 시 트윗 삭제이다. 여기에 추가로 select와 option을 활용해 선택한 사용자가 쓴 글만 보이도록 하는 드롭다운 메뉴가 필요하다. 

드롭다운 메뉴 만들기

  • 먼저 드롭다운 메뉴를 만들기 위해서.. 처음에는 컴포넌트로 생각하고 접근했다. 이 부분까지 컴포넌트로 따로 분리하여 작성하는 것이 맞는지 잘 모르겠는데, 분리해서 작업을 한 결과 과정이 꽤 복잡했기 때문에 이렇게 작은 부분까지 컴포넌트로 분리할 필요는 없겠다는 생각이 들었다. (물론 상황에 따라 다르겠지만...) 
  • 아래 코드가 그 삽질의 결과물이다.(즉 일부만 작동된다..) Tweets 페이지 컴포넌트에서 호출되는 Selection 컴포넌트인데, props로 전체 트윗 목록과, 트윗목록(state) 갱신 함수, 그리고 이전 트윗 목록의 상태를 전달받는다. 나머지 동작들은 괜찮았는데(?) 안 되는 부분은 목록에서 초기 옵션을 클릭 시 전체 목록을 다시 렌더링 하는 부분이었다.
  • 목록에서 초기 옵션을 선택했을 때 전체 목록을 표시하기 위해서 직전 트윗 목록을 가져와서 리렌더링을 했었다. 문제는 한 번 바뀐 상태는 괜찮지만 두 번 바뀌었을 때는 직전의 state도 이미 바뀐 값이기 때문에 변경이 적용된다는 것이다. useEffect와 useRef를 활용해 직전 상태를 만들어준 것은 좋았지만, 그런 부분을 생각하지 못했다. 
  • 이 모든 문제가 기존 tweet 목록과 filtered 된 tweet 목록을 별도의 state로 구분했어야하는데 그러지 않았기 때문에 생긴 일인 것 같다. 렌더링 하면서 기존 tweet 목록을 변경하니까 이전 값이나 원래 목록으로 아무리 돌아가고 싶어도 돌아갈 곳이 없는 것이다 ㅜㅜ. 
const Selection = props => {
  const {tweets, renderTweets, prevTweets} = props;
  const onChangeSelection = e => {
    const val = e.target.value;
    if (val !== 'false') {
      const tweet = tweets.filter(ele => ele.username === e.target.value);
      renderTweets(tweet);
    } else {
      renderTweets(prevTweets);
      console.log(prevTweets);
    }
  };
  const tweetsUsernames = [...new Set(tweets.map(tweet => tweet.username))];
  return (
    <select onChange={onChangeSelection}>
      <option value={false}> --- 사용자 이름 선택 --- </option>
      {tweetsUsernames.map((name, idx) => {
        return (
          <option value={name} key={idx}>
            {name}
          </option>
        );
      })}
    </select>
  );
};
 // 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로 만들어서 그것을 기준으로 필터링한 새 배열을 만들어서 뿌려주었는데, 이런 접근도 가능하다는 것을 새롭게 알게 되었다. 아래는 코드의 일부.
 // Tweets 컴포넌트 내부에 정의된 필터링 함수
 const handleFilter = e => {
    if (e.target.value === 'All') {
      setTweets(tweets);
      setIsFiltered(false);
    } else {
      const filtered = tweets.filter(tweet => tweet.username === e.target.value);
      setFilteredTweets(filtered);
      setIsFiltered(true);
    }
  };
  
  return (
  <select onChange={handleFilter}>
          <option value="All"> --- 사용자 이름 선택 --- </option>
          {tweetsUsernames.map((name, idx) => {
            return (
              <option value={name} key={idx}>
                {name}
              </option>
            );
          })}
        </select>
  // ---
  <ul className="tweets">
        {isFiltered
          ? filteredTweets.map(tweet => {
              return <Tweet tweet={tweet} key={tweet.id} handleDelete={handleDelete} />;
            })
          : tweets.map(tweet => {
              return <Tweet tweet={tweet} key={tweet.id} handleDelete={handleDelete} />;
            })}
      </ul>
  );
  • 추가적으로 트윗 삭제 기능은 아직 구현을 못했다 ㅜ. 레퍼런스가 있긴 하지만 조금 복잡하기도 하고, 다른 예제를 활용해서 만들면서 연습하려고 한다. 

SUMMARY

잘한 점

  • 오전에 알고리즘 문제 풀고, 타입스크립트 공부하고, 블로깅 한 것!

보완할 점

  • 지금까지 배운 리액트 state, props 개념을 활용해서 간단한 todo 앱을 만들면서 복습하면 좋을 것 같다! 이번 주 주말까지 만들고 결과물 블로그에 업로드해보기.

느낀 점

  • 오늘 어려웠던 점은 어떤 부분을 state로 등록해야할지 감이 잘 오지 않는 것이었다. 변하는 모든 부분이 state는 아닐 것이고, 또 어떤 관점으로 state를 바라보느냐에 따라서 코드의 방향이 바뀐다고 생각하니까 좀 더 신중하게 생각하고 접근해야겠다고 느꼈다. 
  • 페어님이 앞부분 챌린지를 미리 끝내고 오셔서 오늘은 거의 따로 진행을 했다. 나도 지금까진 과제를 미리 해오는 부분에 있어서 별 생각이 없었던 것 같은데, 그래도 같이 하는 것에 의미가 있다고 있는 것 같다. 앞으로는 페어를 좀 더 배려하려고 노력해야 되겠다는 생각이 들었다...! 
  • 재미가 있으면서도, 더 많이 빨리 배우려면 이것을 왜 이렇게 써야되는지 '왜????' 라는 의문을 늘 품고 공부해야 하는 것 같다. 

 

 

저작자표시 (새창열림)

'TIL' 카테고리의 다른 글

[Day 32] 2022-0805  (0) 2022.08.08
[Day 31] 2022-0804  (0) 2022.08.05
[Day 29] 2022-0802 : props, state 활용해 SPA 만들기  (0) 2022.08.03
[Day 28] 2022-0801 : SPA와 리액트 라우터/ useNavigate  (0) 2022.08.01
[Day 26] 2022-0728 : fetch API 다양한 방법으로 활용하기  (0) 2022.07.29
    'TIL' 카테고리의 다른 글
    • [Day 32] 2022-0805
    • [Day 31] 2022-0804
    • [Day 29] 2022-0802 : props, state 활용해 SPA 만들기
    • [Day 28] 2022-0801 : SPA와 리액트 라우터/ useNavigate
    프라이D
    프라이D
    틀린내용 정정 및 개선사항은 언제든지 댓글 달아주세요 :D

    티스토리툴바