• 웹 크롤러가 웹페이지를 수집할때는 meta 태그를 읽는다
$ yarn add react-helmet-async
  • src/index.js파일을 열어서 HelmetProvider 컴포넌트로 App 컴포넌트를 포장
  • src/App.js 파일에 태그를 설정
  • 각각의 pagesHelmet의 태그를 추가
  • 각각의 componentsHelmet의 태그 추가
  • 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';

한페이지에 여러 컴포넌트를 넣고 싶은 경우가 있다. 예를 들어서 왼쪽은 전화번호부 오른쪽은 채팅창! 그럴때는 아래와 같이 코드를 작성하면 된다.

function SplitPane(props) {
  return (
    <div className="SplitPane">
      <div className="SplitPane-left">
        {props.left}
      </div>
      <div className="SplitPane-right">
        {props.right}
      </div>
    </div>
  );
}

function App() {
  return (
    <SplitPane
      left={
        <Contacts />
      }
      right={
        <Chat />
      } />
  );
}

위처럼 작성하면 App에서 왼쪽은 Contacts, 오른쪽은 Chat의 컴포넌트가 화면에 렌더링 된다.

key는 element의 리스트를 사용할때 꼭 명시해줘야 한다. 아래 소스코드를 참고하면 

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <li key={number.toString()}>
      {number}
    </li>
  );
  return (
    <ul>{listItems}</ul>
  );
}

위에서 li의 element에서 key를 사용하지 않으면 경고가 표시된다. 

React에서 Key의 역할은 어떤 항목을 변경, 추가 또는 삭제할지 식별하는 것을 돕는다. 그렇기 때문에 리스트 element에서 값의 업데이트를 위해서는 반드시 적어줘야 하는데, 이때 각각 element는 고유한 key를 갖고 있어야 하고, 보통은 데이터의 id를 사용한다. 

id가 없다면 최후의 수단으로 항목의 index를 키로 사용할 수 있는데, 이렇게 사용하면 성능이 저하되거나 컴포넌트의 state와 관련한 문제가 발생할 수 있으니 명시적으로 id를 적어주는게 좋다.

위에서 index를 지정하지 않으면 경고가 뜬다고 했는데, 그 이유도 기본으로 index를 key로 사용하기 때문에 표시되는 방법이다. (권장하지 않는다는 뜻!)

컴포넌트 추출하기

컴포넌트로 Blog를 추출하고 리스트의 값을 표시하기 위해서는 아래와 같이 코드를 작성하면 된다.

function ListItem(props) {  
  return <li>{props.value}</li>;
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) => 
    <ListItem key={number.toString()}
              value={number} />

  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);
function Blog(props) {
  const sidebar = (
    <ul>
      {props.posts.map((post) =>
        <li key={post.id}>
          {post.title}
        </li>
      )}
    </ul>
  );
  const content = props.posts.map((post) =>
    <div key={post.id}>
      <h3>{post.title}</h3>
      <p>{post.content}</p>
    </div>
  );
  return (
    <div>
      {sidebar}
      <hr />
      {content}
    </div>
  );
}

const posts = [
  {id: 1, title: 'Hello World', content: 'Welcome to learning React!'},
  {id: 2, title: 'Installation', content: 'You can install React from npm.'}
];
ReactDOM.render(
  <Blog posts={posts} />,
  document.getElementById('root')
);
 

+ Recent posts