정리할 내용

  • [] searchUser, searchPost 합쳐서 query 만들기
  • [] search 컴포넌트 Container, Presenter, Queries, index로 나누기
  • [] 이미지 overlay 방법
  • [] display : grid 적용하기

searchUser, searchPost 합쳐서 query 만들기

Search부분은 Post와 User를 동시에 검색하는 방식을 사용했습니다. Search컴포넌트는 크기가 클 것이기 때문에 Container Presenter 방식으로 작성했습니다.

apollo-boost의 gql을 사용해서 query를 제작했고, 단순히 정보를 조회하기 위함이기 때문에 Mutation이 아닌 Query를 사용했습니다.
게시물은 카드형태로 제작할 것이기 때문에 사진과 좋아요,댓글 갯수만 있으면 됩니다. 유저는 아바타와 이름, 팔로우 여부,자기자신 여부를 받아와야 합니다. gql의 장점인 모든 데이터를 가져와서 처리하는 것이 아닌 필요한 데이터만 호출하는 방식으로 작성하니 보기 편한 것 같습니다.

//searchQueries.js

import { gql } from "apollo-boost";

export const SEARCH = gql`
  query search($term: String!) {
    searchPost(term: $term) {
      id
      likeCount
      commentCount
      files {
        id
        url
      }
    }
    searchUser(term: $term) {
      id
      username
      avatar
      isSelf
      isFollowing
    }
  }
`;

Query를 만들었으면 Query를 호출할 Container를 제작해야합니다.

withRouter가 필요한 이유는 검색을 하게 되면 주소 뒤에 /search?term=검색내용이 붙게 해놨기 때문입니다. 아래 코드를 보면 검색 창에서 enter를 입력하면 onsubmit이 호출됩니다. 우선 form이 제출되는 것을 막기위해 e.preventDefault()를 했고, history.push()Router에서 기본적으로 하위 컴포넌트에게 history match location을 넘겨줍니다.

image

history,match,location에 대해서는 정리가 잘된 사이트가 많기 때문에 간단히 정리하고 넘어가도록 하겠습니다.

  • history
    브라우저의 window.history 와 유사
    주소를 임의로 변경하거나 되돌아 갈 수 있도록 한다.
    주소 변경시, SPA 특성을 지키기 위해 페이지 전체를 리로드 하지 않는다.
    location 이 포함되어 있다.

  • location
    브라우저의 window.location 와 유사
    현재 페이지 정보를 지니고 있다.
    url의 query 정보를 search라는 프로퍼티에 가지고 있다.

  • match
    Route의 path에 정의한 것과 매칭된 정보를 가지고 있다. params 에 설정한 파라미터를 담고 있다.

그래서 Header에서 history를 props로 받을 수 있던 것 입니다.
history.push를 하게 되면 a링크처럼 이동하게 되지만 새로고침은 하지 않게 됩니다.

//Header.js

export default withRouter(({ history }) => {
  const search = useInput("", "text");
  const {
    data: { me }
  } = useQuery(ME);
  const onSubmit = e => {
    e.preventDefault();
    history.push(`/search?term=${search.value}`);
  };
  
  (...중략...)

Query를 쉽게 호출할 수 있게 해주는 react-apollo-hooks를 사용했습니다. 이번엔 Router의 location을 사용해서 검색한 정보를 얻어냈습니다. 아래와 같이 13을 검색하게 되면 Router의 location의 searchsearch?term=13이 들어가는 것을 확인할 수 있습니다. 이 것으로 검색 Query문에 넣은 데이터를 얻을 수 있는 것입니다.

검색(history.push로 이동) -> search컴포넌트에서는 location의 search를 받아서 Query에 넣을 데이터를 얻음.

image

//searchContainer.js

import React from "react";
import { withRouter } from "react-router-dom";
import { useQuery } from "react-apollo-hooks";
import SearchPresenter from "./SearchPresenter";
import { SEARCH } from "./SearchQueries";

export default withRouter(({ location: { search } }) => {

  const term = search.split("=")[1];
  
  const { data, loading } = useQuery(SEARCH, {
    skip: term === undefined,
    variables: { term }
  });
  
  return <SearchPresenter term={term} data={data} loading={loading} />;
});

끝으로

history 개념을 몇일 동안 기억할지는 모르겠지만 나중에 봤을 때 생각만 나면 다행일 것 같다….