React ch.2 React Component (1) ~ (7)

01. 컴포넌트 작성방법

1) class 컴포넌트 작성법

import React from 'react';
// 정의
    class ClassComponent extends React.Component {
      render() {
        return <div>Hello</div>;
      }
    }
// 사용
   ReactDOM.render(
     <ClassComponent />,
      document.querySelector('#root')
   )

2) Function 컴포넌트 작성법

  • 1번째 방법 (Function 키워드 사용)
import React from 'react';
// 정의
    function FunctionComponent() {
      return <div>hello world</div>;
    }
// 사용
    ReactDOM.render(
      <FunctionComponent />, 
      document.querySelector('#root')
    );
  • 2번째 방법
import React from 'react';
// 정의
    const FunctionComponent = () => <div>Hello World</div>;
// 사용
    ReactDOM.render(
      <FunctionComponent />, 
      document.querySelector('#root')	
    );

02. React.createElement 로 컴포넌트 만들기

1) React.createElement 구성요소

React.createElement(
      type, // 태그 이름 문자열 | 리액트 컴포넌트 | React.Fragment
      [props], // 리액트 컴포넌트에 넣어주는 데이터 객체
      [...children] // 자식으로 넣어주는 요소들
    );

- 태그 이름 문자열 type

ReactDOM.render(
      React.createElement('h1', null, `type이 "태그 이름 문자열" 입니다.`),
      document.querySelector('#root')
    );

// <h1>type이 "태그 이름 문자열" 입니다.</h1>

- 리액트 컴포넌트 type

const Component = () => {
      return React.createElement(
        'p',
        null,
        `type이 "React 컴포넌트" 입니다.`
      );
    };
    
ReactDOM.render(
    React.createElement(Component, null, null),
    document.querySelector('#root')
  )
    
// <Component></Component> => <Component /> => <p>type이 "React 컴포넌트" 입니다.</p>

- React.Fragment

ReactDOM.render(
      React.createElement(
        React.Fragment,
        null, 
        `type이 "React.Fragment" 입니다`
      ),
      document.querySelector('#root')
    )
    
// <div id="root">type이 "React.Fragment" 입니다</div>

=> 태그 없이 띠용하게 들어감

- 복잡한 리액트 엘리먼트 모임

ReactDOM.render(
      React.createElement(
        'div', 
        null, 
        React.createElement(
          'div', 
          null, 
          React.createElement('h1', null, "주제"),
          React.createElement(
            'ul', 
            null, 
            React.createElement('li', null, "React"),
            React.createElement('li', null, "Vue")
          )
        )
      ),
      document.querySelector('#root')
    )
    
// <div>
//   <div>
//     <h1>주제</h1>
//     <ul>
//       <li>React</li>
//       <li>Vue</li>
//     </ul>
//   </div>
// </div>

03 JSX

JSX 문법으로 작성된 코드는 순수한 자바스크립트로 컴파일하여 사용

누가 해주나요? BABEL!!

Babel 사용

<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
 ReactDOM.render(
      <div>
        <div>
          <h1>주제</h1>
          <ul>
            <li>React</li>
            <li>Vue</li>
          </ul>
        </div>
      </div>,
      document.querySelector('#root')
    )
</script>

왜 JSX를 쓰는가?

  • React.createElement와 비교하였을 때, 가독성 완승
  • Babel과 같은 컴파일 과정에서 문법적 오류를 인지하기 쉬움

JSX 문법

  • 최상위 요소가 하나여야 함
  • 최상위 요소를 리턴하는 경우, ()로 감싸야 함
  • 자식들을 바로 랜더링하고 싶을 때는 <>자식들</> 를 사용 => Fragment
  • 자바스크립트 표현식을 사용하려면 {표현식} 사용
  • if문은 사용할 수 없음
    • 삼항연산자
    • &&사용
  • style을 이용해서 인라인 스타일링 가능
  • class 대신 classname을 사용해 class 적용
  • 자식요소가 있으면 꼭 닫아야 하고, 없으면 열면서 닫아야 함
    • <p>어쩌구</p>
    • <br />

04 Props와 State

(1) Props와 State

  • Props: 컴포넌트 외부에서 컴포넌트에게 주는 데이터
  • State: 컴포넌트 내부에서 변경할 수 있는 데이터
    => 둘 다 변경이 발생하면 랜더가 다시 일어날 수 있음

(2) Render 함수

Props와 State를 바탕으로 컴포넌트를 그림
그리고 Props와 State가 변경되면 다시 컴포넌트를 그림
컴포넌트를 그리는 방법을 기술하는 함수가 바로 Render 함수

(3) props를 사용한 함수 컴포넌트

function Component(props) {
      return (
        <div>
          <h1>{props.message} 이것은 함수로 만들어진 컴포넌트입니다.</h1>
        </div>
      );
    }
    
ReactDOM.render(
      <Component message="안녕하세요!"/>,
      document.querySelector('#root')
    )

(4) props를 사용한 클래스 컴포넌트

class Component extends React.Component {
      render() {
        return (
        <div>
          <h1>{this.props.message} 이것은 클래스로 만들어진 컴포넌트입니다.</h1>
        </div>
        );
      }
    }
    
ReactDOM.render(
      <Component message="안녕하세요!"/>,
      document.querySelector('#root')
    )

- props default 값 지정

컴포넌트를 사용할 때 props를 지정해주지 않으면 undefined로 저장되어 화면에 나타나지 않음
컴포넌트 사용 시 props를 지정하지 않아도 props 기본값을 미리 지정하여 화면에 나타나게 할 수 있음

- 첫 번째 방법: class와 function 모두 사용 가능

Component.defaultProps = {
      message: '기본값'
    }

- 두 번째 방법: class에서만 사용 가능

class Component extends React.Component {
      render() {
        return (
        <div>
          <h1>{this.props.message} 이것은 클래스로 만들어진 컴포넌트입니다.</h1>
        </div>
        );
      }

      static defaultProps = {
        message: '기본값2',
      }
    }

(5) state를 사용한 클래스 컴포넌트

  • 첫 번째 방법
class Component extends React.Component {
      state = { // 항상 객체, 주로 많이 쓰이는 방법
        count: 0,
      }

      render() {
        return (
        <div>
          <h1>{this.props.message} 이것은 클래스로 만들어진 컴포넌트입니다.</h1>
          <p>{this.state.count}</p>
        </div>
        );
      }

      componentDidMount() { // 객체를 아예 만듬
        setTimeout(() => {
          this.setState({
            count: this.state.count + 1,
          });
        }, 1000);
      }

      static defaultProps = {
        message: '기본값2',
      }
    }
  • 두 번째 방법
class Component extends React.Component {
      constructor(props) {
        super(props);

        this.state = { count: 0 }
      }

      render() {
        return (
        <div>
          <h1>{this.props.message} 이것은 클래스로 만들어진 컴포넌트입니다.</h1>
          <p>{this.state.count}</p>
        </div>
        );
      }

      componentDidMount() {
        setTimeout(() => { // 이전 값을 이용함
          this.setState((previousState) => {
            const newState = { count: previousState.count + 1 }
            return newState;
          })
        }, 1000);
      }

      static defaultProps = {
        message: '기본값2',
      }
    }

05. Event Handling

HTML DOM에 클릭하면 이벤트가 발생하고 발생하면 그에 맞는 변경이 일어남
JSX에 이벤트 설정 가능(props에 넣는 것)

class Comp extends React.Component {
	render() {
    	return (
        <div>
        	<button onClick={() => {
            	console.log('clicked');
            }}>클릭</button>
        </div>
        );
    }
}
  • 이벤트명은 카멜케이스만 사용 가능(on을 붙여야 함)
    • onClick, onMouseEnter
  • 이벤트에 연결된 자바스크립트 코드는 함수
    • 이벤트={함수} 와 같이 씀
  • 실제 DOM 요소들에만 사용 가능
    • 리액트 컴포넌트에 사용하면 그냥 props로 전달됨

(1) function 컴포넌트 이벤트 핸들링

    function Component () {
      return (
        <div>
          <button 
            onClick={() => {
            console.log("clicked");
            }}
          >
            클릭
          </button>
        </div>
      )
    }

    ReactDOM.render(<Component />, document.querySelector('#root'));

(2) class 컴포넌트 이벤트 핸들링

class Component extends React.Component{
      render() {
        return (
          <div>
            <button 
              onClick={() => {
              console.log("clicked");
              }}
            >
              클릭하십쇼
            </button>
          </div>
        );
      }
    }

    ReactDOM.render(<Component />, document.querySelector('#root'));
  • class 컴포넌트 응용
class Component extends React.Component{
      state = {
        count: 0,
      };
      render() {
        return (
          <div>
            <p>{this.state.count}</p>
            <button 
              onMouseEnter={() => {
              console.log("clicked");
              this.setState((state) => ({
                ...state,
                count: state.count + 1,
                }));
              }}
            >
              올려보십쇼
            </button>
          </div>
        );
      }
    }

    ReactDOM.render(<Component />, document.querySelector('#root'));

06. Component Lifecycle (~v16.3)

Component Lifecycle

리액트 컴포넌트는 탄생부터 죽음까지 여러 지점에서 개발자가 작업이 가능하도록 매서드를 오버라이딩 할 수 있게 해줌

  • Declarative
    탄생부터 죽음까지의 순간순간을 선언적으로 표현해놓음 -> 리액트 컴포넌트가 해당 상황 발생 시, 선언적으로 표현된 함수들 실행해서 사용할 수 있게 해줌
    => 효과적으로 처리 가능

(1) Component 생성 및 마운트

constructor
=> componentWillMount
=> render(최초 render, state가 변경될 때마다 render 됨)
=> componentDidMount

(2) Component props, state 변경

componentWillReceiveProps
=> shouldComponentUpdate
=> componentWillUpdate
=> componentDidUpdate

componentWillReceiveProps

  • props를 새로 지정했을 때 바로 호출
  • 여기는 state의 변경에 반응하지 않음
    • 여기서 props의 값에 따라 state를 변경해야 한다면,
      • setState를 이용해 state를 변경
      • 그러면 다음 이벤트로 각각 가는 것이 아니라 한번에 변경됨

shouldComponentUpdate

  • props만 변경되어도
  • state만 변경되어도
  • 둘 다 변경되어도
  • newProps와 newState를 인자로 호출
  • return type이 boolean임
    • true면 render
    • false면 render 호출 안 됨
    • 이 함수를 구현하지 않으면 기본값은 true

componentWillUpdate

  • 컴포넌트가 재 랜더링 되기 전에 불림
  • 여기서는 setState 가튼 것을 쓰면 안 됨

componentDidUpdate

  • 컴포넌트가 재 랜더링이 다 된 직후에 불림

(3) Component 언마운트

componentWillUnmount

07 Component Lifecycle (v16.3)

Component 라이프사이클 변경


=> 이전 버전과 같이 쓰면 에러가 남

(1) getDerivedStateFromProps

static getDerivedStateFromProps(nextProps, prevState) {
        console.log('getDerivedStateFromProps',nextProps, prevState);
        return null;
      }

=> static을 명시해주어야 함
=> return이 꼭 필요함(리턴할게 없어도 null 명시)

(2) componentDidCatch

좋은 웹페이지 즐겨찾기