본문 바로가기

프론트엔드/리액트

[리액트] 기본 개념 익히기

React

[참고]

주요개념가이드 ko.reactjs.org/docs/hello-world.html

 

Hello World – React

A JavaScript library for building user interfaces

ko.reactjs.org


1) JSX

- javascript 확장 문법 ( 마크업 + JS )

- 기본적으로 html 보다 javascript 객체로 인식 

- 문자열(따옴표) 및 표현식(중괄호) 삽입 가능

- 리액트 엘리먼트로 표현 가능 ( React.createElement(...) )

 

2) 렌더링

ReactDOM.render(렌더링 대상 엘리먼트, DOM 노드);

렌더링 대상 엘리먼트 : const element = <h1>Hello, {name}</h1>; (JSX 표현식)
DOM 노드 : document.getElementById('root')

 

3) 엘리먼트

- DOM 태그 혹은 사용자 정의 컴포넌트 모두 가능

- 엘리먼트는 불변객체 ☞ 화면 UI를 업데이트 하려면 새로운 엘리먼트 생성 후 ReactDOM.render 다시 태워줘야 함

- ReactDOM 자체적으로 변경된 부분만 감지해 효율적으로 DOM을 변경할 수 있도록 지원

 

 

4) 컴포넌트와 props

- 함수형 컴포넌트 or React.Compnent를 상속받은 클래스 컴포넌트(ES6기반)

// 함수형 컴포넌트
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}


// 클래스형 컴포넌트
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

const element = <Welcome name="Kline" />;
ReactDOM.render(
  element,
  document.getElementById('root')
);

 - nested 가능 (컴포넌트 합성)

 - props는 읽기 전용 (컴포넌트는 순수함수처럼 동작. props를 변경하면 안됨)

 - 함수형 컴포넌트는 props를 파라미터로 명시하지만 클래스형은 생성자 메서드를 사용할 경우만 constructor의 인자로 전달하고 그게 아닌 경우 따로 명시하지 않아도 클래스 내에서 this.props로 접근한다.

 

 

5) State와 생명주기

- props와 유사하지만 private, 컴포넌트에 의해 제어

- state업데이트를 위해 setState() 사용

- UI 업데이트를 위해 State로 변경되는 인스턴스를 감지하고 재렌더링을 하는 경우 class 형태로 컴포넌트를 만들고 사용하는걸 권장 (클래스의 싱글톤 패턴에 의거. 렌더링 메서드 재호출 시에도 단일 인스턴스 사용으로 메모리 고정)

함수형 컴포넌트와 hook의 지원이 강력해졌습니다!

class Clock extends React.Component {
  constructor(props) {
    super(props);
  	// 내용    
  }
  
  render() {
  	// 내용
  }
}

 

- 사용방법(클래스형)

(1) 클래스 constructor 내에서 this.state에 상태변화 감지를 원하는 인스턴스를 오브젝트 형식으로 할당

  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

 

* 클래스 컴포넌트의 생성자는 항상 props를 기본 인자로 가짐

(2) 클래스 렌더링 메서드의 엘리먼트 내에서 'this.props.인스턴스명' 대신 'this.state.인스턴스명'으로 사용 

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }

 

(3) ReactDOM.render에 위에서 생성한 클래스 엘리먼트를 넘김

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

 

- 생명주기 메서드 (컴포넌트 생명주기를 관리하는 특수 메서드)

componentDidMount() : 컴포넌트가 DOM에 렌더링 된 이후 실행

componentWillUnmount() : 컴포넌트가 DOM에서 삭제될 때 실행

 

-주의사항

(1) constructor에서 state 초기값 할당 후 절대 state에 직접 접근하지 말 것. 대신 setState 사용

 ex) this.state.data = 'newData'; 대신 this.setState({data: 'newData'})

(2) props와 state 업데이트는 비동기적. 따라서 setState 내에서 this.props와 this.state의 현재값을 맹신하지 말 것. 

 대신 함수형 인자를 받는 setState()에서 파라미터로 props와 state를 받아 사용하는걸 권장

// 잘못된 접근
this.setState({
  counter: this.state.counter + this.props.increment,
});

// 옳은 방식
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));

3) 독립적인 state 내 인스턴스들은 각각 독립적으로 업데이트 가능 

 

- 부모의 state를 자식 컴포넌트에게 props로 전달 가능

 

 

6) 이벤트 처리

- JSX 표현식에 의거해 중괄호로 감싼 핸들러 함수명 전달 

- 이벤트 동작 방지를 위해서는 e.preventDefault() 를 반드시 실행할 것. false 리턴만으로는 불가

- this 바인딩 주의 (도큐먼트 참조, 퍼블릭 클래스 필드 문법?)

- 엔간하믄 화살표 함수 쓰자 

<Component onClick={()=>this.handleClick}/>
<Component onClick={()=>{~~~}}/>

 

7) 렌더링 제어

- 조건부 연산으로 렌더링 제어 가능