FE 21일차 20강

jae·2022년 6월 6일
0

구글링 그거 어떻게 하는건데..
왜 나만 안나오는 건데...

키워드만 잘라서 넣으면 잘나온다고 하는데
영어권 페이지가 대부분이라서 이해하기 어렵고
수료하면 영어 공부한다 다짐만 오천번째 ㅠㅠ


주간 목표

  1. 글로벌 스테이트 Recoil
  2. 로그인의 역사 AccessToken/RefreshToken
  3. Next.js 렌더링의 원리 diffing/Hydration
  4. 잠깐 이것먼저 실행해줘! Closure/ HOC /HOF
  5. 폼을 자동으로 만들어준다고! React-Hook-Form

리액트 20강

20일차 중간고사?하느라 21일 차지만 20강...!
종강까지 53일..!
곧 포트폴리오 배포하기 위한 도메인 구매도 준비하고 백 컴퓨터도 하나 빌려야함.

  1. 검색을 이행하려면 다양한 DB를 알아야돼! Database
  2. 검색 결과를 페이지 네이션과 연결해야해!Search/pagination
  3. 검색하기 버튼 없이 검색을 한다고? Debouncing/Throttling

\

포트폴리오 리뷰

이제 프리보드 포트폴리오는 거의 끝마무리 단계..!
다음 프로젝트부터는 리뷰없이 자체적으로 알아서 만들어야한다

이렇게 잘만들어진 컴포넌트가 있다면
다른 프로젝트나 다른 페이지에서 만들수 있다.
이미지를 올리는 컴포넌트의 경우 중고마켓이나 회원 프로필 등등 여러곳에서 쓸수 있다.

그럴경우 공통 컴포넌트로 빼서 파일을 페이지네이션 처럼 아예 commons폴더등으로 분리해둔다.

이럴때 fileUrl에서 a.jpg index는 0을 전달한다.
fileurls를 useState를 통하여 빈 배열 형식으로 인덱스 2의 형태를 만들어 두었기에
인덱스 0번째의 빈배열에 a.jpg를 채우라는 뜻.
또한 fileurl을 얕은 복사를 하였기에 원본의 내용이 복사됨.

Props를 통하여 컴포넌트를 통해 내려가는데
fileUrl에는 이제 올리고자하는 파일이 담겨있다.

혹시라도 업로드가 되어있는 상태에서
다른 사진으로 파일을 변경할수도 있기에
그 상황을 위해 삼항연산자로 코드를 만들어두면된다.

이렇게 한번 잘 만들어둔 코드로 같은 성능을 만들고자 할때
이미 만들어둔 컴포넌트들을 사용하면 되기에 편리하다.

태그 코드에 번호를 붙이거나 이름이나 특징을 적어 만드는데
같은 코드를 쓰더라도 스타일등이 달라질수 있어서 구분을 하기위해 태그를 사용한다.

              {props.data?.fetchBoard.images
                ?.filter((el: string) => el)
                .map((el: string) => (
                  <S.Image
                    key={el}
                    src={`https://storage.googleapis.com/${el}`}
                  />
                ))}

이렇게 필터를 통하여 el !=="" 하게 되면 사진 파일이 있는 경우에는 맵을 통하여 뿌려질수 있게 해야한다.
파일이 있으면 true로 변경되고 그 파일은 남아서 전달 되는 것이기에
el !=="" 뿐 아니라 그냥 파일이 있으면 true가 될 수있게 코드만 설정하면 된다.
(el만 써도 가능)

이미지 수정에서는 useEffect를 쓸 수 있는데
파일이ㅣ 있을 경우에
얕은 복사를 통하여 파일 Url을 변경하고 데이타를 확인할수 있게 만든다


이렇게 각각 저장되어 있는 주소가 다른데 그걸 비교를 하면
기본적으로 false가 나오지만 문자열로 담게 되면 true가 나오게됨

이렇게 변경이 일어났다면 수정이 될수 있게 처리를 해두면된다.


1. 검색을 이행하려면 다양한 DB를 알아야돼! Database

브라우저에서 search 를 통하여 원하는 키워드를 입력하고
백에 있는 fetch----s같은 목록에서 찾을 수 있게 요청을 보낸다.
이미 브라우저에서는 패치가 되어있기에 리패치를 해야하는 것

백에서 Db를 찾아 전달을 해주면 프론트는 그것을 그릴수 있는 화면을 그려주기만 하면 된다.
리패치를 했으니깐 브라우저 화면이 검색 전 후에 변경이 되어야한다.
검색기능은 대부분 백에서 이뤄지고 프론트는 전달을 하는 역할

하지만 백에서 기능이 어떻게 이뤄지는 지 알고 있어야 협업을 하기 쉽다!

디비에 저장해둔 게시물들을 키워드를 통하여 찾아오는데
이것을 테이블 풀스캔이라 한다.

검색으로 유명한 구글 엔진..
구글이 검색엔진을 만들때의 초기 원래는
데이터베이스에 있는 모든 내용을 단어로 잘라서 테이블을 하나 더 만들어서
단어를 해당 아이디에 저장하였다.
(단어를 쪼개는 작업은 tokenizing)

그래서 단어를 검색하면 그 단어가 들어간 게시글이 어떤 게시글인지 찾아서 보여준다
(역 인덱스(inverted index))

이런 역인덱스를 대신 해주는 데이터 베이스가 나왔는데
ElasticSearch(ELK스택)이다.

메모리 램에 저장하는 것

디스크 저장공간에 저장하는 것
디스크는 영구저장이 되지만 속도가 느림

속도가 느리더라도 안전성을 중요시하기에 db는 디스크에 저장이 되고 이용이 되는 것

메모리 데이터 베이스(.Redis)도 있는데
영구저장이 아니라 안정성은 낮지만 임시저장(캐싱)을 하여 이용하기에 속도는 훨씬빠르다.
Redis에 자주검색 것을 임시저장하여 보내주면 빠르게 이용할 수 있고
추가적인 내용은 디스크의 db에서 찾아 보내면 된다

프론트는 이과정을 통한 데이터들을 variables로 연결하여 브라우저로 보내주기만 하면된다.


2. 검색 결과를 페이지 네이션과 연결해야해! Search/pagination

export default function MapBoardPage() {
  const { data, refetch } = useQuery(FETCH_BOARDS);
  const { search, setSearch } = useState("");

  const onClickPage = (event) => {
    refetch({ page: Number(event.target.id) });
  };
  const onChangeSearch = (e: ChangeEvent<HTMLInputElement>) => {
    setSearch(e.target.value);
  };
  const onClickSearch = () => {
    refetch({ search: search, page: 1 });
  }; // 백에서 만든 독스 : 내가 만든 스테이트 ,검색결과의 몇페이지

  return (
    <div>
      검색어 입력: <input type="text" onChange={onChangeSearch} />
      <button onClick={onClickSearch}>검색하기</button>
      {data?.fetchBoards.map((el: any) => (
        <MyRow key={el._id}>
          <MyColumn>{el.writer}</MyColumn>
          <MyColumn>{el.title}</MyColumn>
        </MyRow>
      ))}
      {new Array(10).fill(1).map((_, index) => (
        <span key={index + 1} id={String(index + 1)} onClick={onClickPage}>
          {index + 1}
        </span>
      ))}
    </div>
  );
}

우선 페이지 구성은 이렇게 된다

맨 위에 검색을 위한 인풋을 그리고 검색 버튼

그리고 검색한 내용을 맵으로 그릴수 있게 하고
목록을 추가적으로 만들 페이지네이션 이렇게이다.

한줄 요약을 하면 검색은 리패치다..!


3. 검색하기 버튼 없이 검색을 한다고? Debouncing/Throttling


  const onClickPage = (event) => {
    refetch({ page: Number(event.target.id) });
  };
  const onChangeSearch = (e: ChangeEvent<HTMLInputElement>) => {
    refetch({ search: e.target.value, page: 1 });
  };

버튼을 없애고 스테이트를 쓸것이 아니라
Refetch를 온체인지의 함수에 넣고 온체인지가 될때마다 내용을 리패치 할수 있게 한다.
온체인지 함수 하나로 리패치를 바로 보낼수 있기에 심플하게 검색을 할수 있다.

쉽지만 하나의 문제가 있는데
체인지가 될때마다 데이터를 받아오기 때문에 네트워크 창을 보게 되면
엄청난 쿼리 요청들이 발생됨
그러면 백엔드에 과부하가 생겨서 요청을 감당하기 힘듦

온체인지가 되고 완료가 된 시점에 패치가 될수 있는 함수를 만든다면
효율적으로 쓸수 있는데 이런 중간 과정을 없애고 결과만 한 번에 실행해주는 것을
디바운싱Debounce이라고 한다

  • 디바운싱: 특정시간을 기준으로 해당시간 내에 요청된 내용들을 무시하는 것
    요청이 통통 튕기는 것을 막는 것

Lodash 라이브러리

yarn add lodash 로 라이브러리를 설치하고

import _ from "lodash";를 임폴트 해온다.

  const getDebousnce = _.debounce((data) => {
    refetch({ search: data, page: 1 });
  }, 1000);

  const onChangeSearch = (e: ChangeEvent<HTMLInputElement>) => {
    getDebousnce(e.target.value);
  };

이렇게 디바운스 함수를 만들어서 사용을 하고
리패치가 일어날 시간을 1000밀리세컨드로 설정한다음
온체인지 함수의 이벤트 타겟을 디바운스 내의 파라미터로 data를 넣어 받아올수 있게한다.
온체인지가 된뒤 1초뒤에 이벤트타겟의 내용을 받아오기에 마지막 한번만 실행이 된다.

실무에서는 1초는 너무 오래 걸리기에 0.2~0.5초로 설정하여 받아온다.

  • 디바운싱(디바운스)과 대비되는 쓰로틀링(쓰로틀)

쭉 가다가 마지막에 실행되는 디바운싱
먼저 실행하고 일정시간동안 기다리는 쓰로틀링

이미 패치가 된 상태에서 스크롤을 내리면 추가적 패치가 되는 무한스크롤같은 기능에서
쓰로틀링이 사용된다.

  • +) 검색하여 찾은 글자에 색깔로 표시하고 싶으면
    데이터베이스에 있는 내용들을 키워드의 앞뒤로 split해서 찾아야한다.
     .replaceAll(keyword, `#$%${keyword}#$%`)
              .split("#$%")

이렇게 키워드 앞뒤로 시크릿 코드를 넣어서
시크릿 코드를 split 하여 쪼갠다.
그래서 이 쪼개진 단어들을 키워드와 비교하여 다르다면 원래의 색
같다면 내가 원하는 색으로 될수 있게 isMatched를 이용한다!

0개의 댓글

관련 채용 정보