• withRouter 함수는 Higher-order Component
  • 라우터에 의해서 호출된 컴포넌트가 아니어도 match, location, history 객체에 접근할 수 있도록 해준다.

    참고로 history 는 match, location과 함께 전달되는 properties 중 하나로 페이지 이탈 방지할때 사용

import React from 'react';
import { withRouter } from 'react-router-dom';

const withRouterSample = ({ location, match, history }) => {
  return (
    <div>
      <h4>location</h4>
      <textarea
        value={JSON.stringify(location, null, 2)}
        rows={7}
        readOnly={true}></textarea>
      <h4>match</h4>
      <textarea
        value={JSON.stringify(match, null, 2)}
        rows={7}
        readOnly={true}></textarea>
      <button onClick={() => history.push('/')}>HOME</button>
    </div>
  );
};

export default withRouter(withRouterSample); 
  • 라우팅을 하는 컴포넌트가 있고, 그 라우팅된 컴포넌트에서 다른 컴포넌트를 사용할때 사용하면 된다.
  • 예를들면 도시의 목록이 있고, 그 도시 목록을 눌렀을때 아래 다른 컴포넌트가 표시될 필요가 있을때!
  • 검색된 결과를 받았을때 그 결과로 화면에 뿌려줘야 하는데 다른 컴포넌트에서도 쿼리가 필요할때

TypeError: Cannot read property 'createElement' of undefined 의 에러가 발생한다면 import 구문을 확인해보자 보통 우리는 여러개의 library를 { }을 사용해서 한번에 import를 하게 된다.

import { .... } from 'library';

클래스 컴포넌트를 생성하기 위해서는 Component를 import를 해야 하는데, 만약 아래와 같이 import 한다면 에러가 발생한다.

import { React, Component } from 'react';

issue 를 살펴보면 아래와 같이 선언을 하라고 한다.

import React, { Component } from 'react';

서브 라우트는 라우트 내부에 라우트를 다시 정의 하는 것을 의미한다. 사용하는 경우에는 App에서 라우팅을 여러군대로 한다면 코드는 App에서 정말 복잡한 결과를 낼것이다. 우리는 여러개의 컴포넌트를 만들고 연관되는 컴포넌트끼리 내부에서 다시 라우터를 정의해 App에서의 다양하고 복잡한 routing을 효과적으로 정리가 가능하다.

예를들어서 Location에 관련된 컴포넌트에서 Location은 Seoul, Gyonggi-do, (...) 가 있을때 App에 모든 도시의 리스트를 정의하기에는 복잡하다. Location Routing Example 에서 App에 seoul, gyonngi-do를 정의 했는데 Locations라는 라우트 컴포넌트를 따로 정의하고, Location 컴포넌트를 서브 라우트로 사용해보자

코드

import React from 'react';
import { Route, Link } from 'react-router-dom';
import './App.css';

import Home from './components/Home';
import Search from './components/Search';
import Locations from './components/Locations';

const App = () => {
  return (
    <div>
      <Link to="/">홈</Link>
      <Link to="/search">검색</Link>
      <Link to="/locations">위치</Link>

      <Route path="/" component={Home} exact={true}></Route>
      <Route path="/search" component={Search}></Route>
      <Route path="/locations" component={Locations}></Route>
    </div>
  );
};

export default App;
import React from 'react';
import { Link, Route } from 'react-router-dom';
import Location from './Location';

const Locations = () => {
  return (
    <div>
      <h1> 도시 목록 </h1>
      <ul>
        <li>
          <Link to="/locations/seoul">서울</Link>
        </li>
        <li>
          <Link to="/locations/gyonggi">경기</Link>
        </li>
      </ul>
      <Route
        path="/locations"
        exact={true}
        render={() => <div> 지역을 선택해 주세요. </div>}
      />
      <Route path="/locations/:cityname" component={Location} />
    </div>
  );
};

export default Locations;

Parameter, Query Example

  • /user/lee
  • /search?keyword="hi

위에서 user에 lee를 넘기는 방식이 parameter로 특정 사용자를 조회할때 사용하고, query는 키워드를 검색할때 페이지에 필요한 옵션을 전달할 때 사용을 하게 된다.

URL Parameter

  • match라는 객체안의 params 값을 참조
import React from 'react';

const data = {
  seoul: {
    name: '서울',
    location: 'seoul'
  },
  gyonggi: {
    name: '경기도',
    location: 'gyonngi-do'
  }
};

const Location = ({ match }) => {
  const { cityname } = match.params;
  const city = data[cityname];
  if (!city) {
    return (
      <div>
        <h1> {cityname} 은 존재하지 않는다.</h1>
      </div>
    );
  }

  return (
    <div>
      <h1>
        {' '}
        {cityname} ({city.name})
      </h1>
      <p>{city.location}</p>
    </div>
  );
};

export default Location;
  • App.js에서 routing을 정의
import React from 'react';
import { Route, Link } from 'react-router-dom';
import './App.css';

import Home from './components/Home';
import Search from './components/Search';
import Location from './components/Location';

const App = () => {
  return (
    <div>
      <Link to="/">홈</Link>
      <Link to="/search">검색</Link>
      <Link to="/location/seoul">서울</Link>
      <Link to="/location/gyonngi">경기</Link>
      <Link to="/location/star">별나라</Link>

      <Route path="/" component={Home} exact={true}></Route>
      <Route path="/search" component={Search}></Route>
      <Route path="/location/:cityname" component={Location}></Route>
    </div>
  );
};

export default App;

URL 쿼리

  • url 쿼리의 경우에는 match와 다르게 location의 객체에 있는 값을 조회가 가능하다.
  • /search?keyword=hi의 url을 호출했을때 location의 객체의 형태는 아래와 같다.
{
  "pathname": "/search",
  "search": "?keyword=hi"
}
  • query 문자열을 객체로 변환할때는 qs의 라이브러리를 사용한다
yarn add qs
import React from 'react';
import qs from 'qs';

const Search = ({ location }) => {
  // ?keyword=
  const query = qs.parse(location.search, {
    ignoreQueryPrefix: true // prefix: ?
  });

  const keyword = query.keyword;

  return (
    <div>
      <h1>Search</h1>
      <p> 검색 쿼리는 {keyword}</p>
    </div>
  );
};

export default Search;
  • 다음과 같이 추가한 이후에 url을 http://localhost:3000/search?keyword=hi을 통해 접속하면 원하는 결과를 얻을 수 있다.

Routing 이란?

routing 은 특정 주소에 특정 페이지를 보여주는게 라우팅(Routing)

react-router 사용하기

default로 react는 routing의 기능이 없기 때문에 라우팅 라이브러리를 사용해야 한다. 가장 많이 사용하는 routing library는 react-router

yarn add react-router-dom

프로젝트에 라우터를 적용

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<App />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

위 코드에서 아래와 같이 추가

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(
  <BrowserRouter>
    <App />{' '}
  </BrowserRouter>,
  document.getElementById('root')
);

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

두개의 컴포넌트 생성하기

import React from 'react';

const Search = () => {
  return (
    <div>
      <h1>Search</h1>
    </div>
  );
};
export default Search;

import React from 'react';

const Home = () => {
  return (
    <div>
      <h1>Home</h1>
    </div>
  );
}; 
export default Home;

App.js 를 수정

  • app에서 exact={true}를 사용하지 않으면 search로 검색했을때 Home, Search의 두개의 페이지가 화면에 중복으로 표시된다.
  • Link를 클릭하면 다른 주소로 이동시켜주는 컴포넌트
  • a tag 를 사용하면 화면이 새로고침 된다. (페이지를 렌더링)
  • Link 사용하면 페이지 새로고침 하지 않고
import React from 'react';
import { Route, Link } from 'react-router-dom';
import './App.css';

import Home from './components/Home';
import Search from './components/Search';

const App = () => {
  return (
    <div>
      <Link to="/">홈</Link>
      <Link to="/search">검색</Link>
      <Route path="/" component={Home} exact={true}></Route>
      <Route path="/search" component={Search}></Route>
    </div>
  );
};

export default App;

EsLint, Prettier는 VS Code에서 React를 개발할때 설치하면 좋은 확장 툴이다.
ESLint는 문법 검사, Prettier는 코드 스타일 자동 정리를 해주는 툴이다.

여러 개발자들이 동시에 개발하는 프로젝트라면 Prettier는 무조건 필수라고 할 수 있다.
git에서 merge할때 indentation 관련한 코멘트를 받으면 ... 창피

ESLint는 설치하고 바로 사용하면 되고, Prettier의 경우에는 프로젝트에 설정을 해야 한다.
프로젝트의 root directory에서 .prettierrc라는 파일을 설정하고
아래와 같이 프로젝트에서 사용할 prettierrc를 정의를 하면된다.

prettierrc example

{
  "semi": true,
  "useTabs": false,
  "tabWidth": 2,
  "singleQuote": true,
  "bracketSpacing": true,
  "jsxBracketSameLine": true
}

prettier에 관련한 옵션은 다음 사이트에서 확인

코드 자동으로 정렬

VS Code에서는 코드를 저장할때 자동으로 정렬을 해준다.

[Code] - [Preference] - [Settings] 
에서 format on save 을 검색하고 체크

Homebrew 설치

 /usr/bin/ruby -e "$(curl -fsSl https://raw.githubusercontent.com/Homebrew/install/master/install)"

nvm 설치

  • node.js 버전 관리 툴
  • node.js의 버전 업데이트를 하거나 프로젝트 별로 버전이 다른 node.js를 사용하기 위해서
sudo curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.1/install.sh | bash
  • 환경설정
# ~/.bsah_profile 에 아래와 같이 추가 (macos 기준)

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" 

node 설치

  • nvm이 설치되었다는 가정하에서아래와 같이 최신 버전으로 설치
nvm install --lts

yarn 설치

brew update
brew install yarn
yarn config set prefix ~/.yarn
echo 'export PATH="$(yarn global bin):$PATH"' >> ~/.bash_profile

Visual Studio Code로 React를 개발하면서 유용한 확장 프로그램을 정리

ESLint

  • 문법 및 코드 스타일을 검사

reactjs Code Snippets

  • 라이프사이클 함수를 작성할때 단축 단어를 사용해 코드 자동 생성

Prettier-Code formatter

  • 내가 설정한 코드 포맷의 스타을로 자동 정리해주는 도구

+ Recent posts