반응형

이 포스트는 직접 React 독학을 하며, 블로그를 만들어 보자는 취지로 작성하게 되었습니다.

오류가 있거나 코드 에러가 나는 부분이 있다면, 댓글 부탁드리겠습니다.

 

참고 문서

 

React – 사용자 인터페이스를 만들기 위한 JavaScript 라이브러리

A JavaScript library for building user interfaces

ko.reactjs.org

 

 

React는 JavaScript 라이브러리이기 때문에 , 배우기 전에 사전 지식이 권장됩니다. JavaScript 언어에 대한 기본적인 이해가 필요합니다. 

 


React는 "JSX"라는 문법을 사용합니다. "JSX"란 JavaScript를 확장한 문법입니다. 형태는 아래와 같습니다.

중괄호 내에 Javasciprt 표현식 사용 가능합니다.

 

const Hello = <h1>Hello, World!</h1>;
const element = <h1>Hello, {name}</h1>;

 

 

자, 우리는 지금 "Hello"라는 엘리먼트를 생성하였습니다. 엘리먼트는 화면에 표시할 내용 기술합니다.

즉, 우리는 브라우저에 렌더링 할 내용을 엘리먼트에 작성하는 것입니다.

엘리먼트는 React 앱의 가장 작은 단위
"브라우저 DOM 엘리먼트와 달리 React 엘리먼트는 일반 객체이며(plain object) 쉽게 생성할 수 있습니다
React DOM은 React 엘리먼트와 일치하도록 DOM을 업데이트합니다."
참조 : "https://ko.reactjs.org/docs/rendering-elements.html"

 

Q. DOM(Document Object Model)(+ 브라우저 DOM)은 무엇일까?

A. 웹 페이지(문서 : Document)에 대한 인터페이스(=객체 지향 표현)이다. 프로그래밍 언어가 접근할 수 있게 하는 API 기능또한 갖고 있다. 

API (web or XML page) = DOM(Document(문서) >  Element(요소)) + JS (scripting 언어)

 

Q. DOM 의 객체지향 표현? 구조는 어떻게 되있을까?

A. "노드 트리" 구조로 표현이 됩니다. 

 

DOM 노드 트리 구조

DOM 에 대해 윤곽이 잡히셨다면, Reactfh DOM에 엘리먼트를 렌더링하는 실습을 진행해봅시다.

우선, React는 ReactDOM.render() 함수를 통해 엘리먼트를 DOM에 전달합니다. (유일한 방법)

React 엘리먼트는 불변객체이며,  UI를 업데이트하는 유일한 방법은 ReactDOM.render()로 전달하는 방법으로 그 외에방법은 없습니다. 

 

아래 예시는 React DOCS에 나와있는 예시입니다. 아래 코드는 1초마다 Clock 함수를 호출하여, 시간값을 받아내어 브라우저 DOM에 표현하는 내용입니다.

function Clock() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  ReactDOM.render(element, document.getElementById('root'));
}

setInterval(Clock, 1000); /// 1초마다, tick 함수 실행

참조 : ko.reactjs.org

 

Q. 그렇다면, React를 사용하여 시간 UI값을 변경할때마다 ReactDOM.render 함수가 페이지 전부를 재 리로드를 하는 것인가요?

 

A. 아닙니다. 위의 코드는 Clock 함수가 호출될때마다 전체 UI(const element)값을 재 랜더링하도록 되어 있지만,

실제로 React DOM내용이 변경된 텍스트 노드만 업데이트를 합니다.

이것이 React 를 사용하는 이유 중 하나라고 보셔도 될거 같습니다.

 

 


이번에는 React의 코어라고 할 수 있는 State and Lifecycle에 대해 알아보도록 하겠습니다. 그 전에 우리는 "컴포넌트" 라는 것에 대해 알 아야 합니다. React에 컴포넌트는 두가지 존재합니다. "함수형 컴포넌트" 와 "클래스형 컴포넌트" 입니다.

위의 코드 function Clock()은 함수형 컴포넌트라고 부릅니다. 아래 코드는 클래스형 컴포넌트라고 부릅니다.

 

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

코드 참조 : ko.reactjs.org

Q. 그렇다면 함수형 컴포넌트를 사용해야 하나요? 클래스형 컴포넌트를 사용해야 하나요?

A. 공식문서에서 함수형 컴포넌트와 리액트 훅(hook)을 같이 사용할 것을 권장하고 있으나, 요구되는 상황에 따라 유동적으로 선택하셔서 사용하시는 것을 권장드립니다.

 

위 함수에 State를 추가해 봅시다. State를 사용하는 방법은 "함수형 컴포넌트" , "클래스형 컴포넌트" 사용 방식이 조금 다릅니다. 

#### 클래스 컴포넌트 State 사용방법 ####
class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

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

#### 함수형 컴포넌트 State 사용방법 ####
function Clock() {
  const [date,setDate] = setState("")
  const processing = () => {
    let result = new Date().toLocaleTimeString()
    setDate(result)
  }
  
  useeffect(() => {processing}
  return (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {date}.</h2>
    </div>
  )
}

function tick() {
  ReactDOM.render(
    <Clock />,
    document.getElementById('root')
  );
}

setInterval(tick, 1000);

 

그 다음으로는 LifeCycle -> "생명주기 메서드"들을 소개해드리겠습니다. 아래 사진과 같이 4가지 단계가 존재합니다. 

 

-. componenetDidMount() : 컴포넌트 출력물이 DOM에 렌더링 된 후에 실행 

위의 코드로 따지면, Hello , world! 화면이 출력된후, {date}값이 Mount가 되는 시간대입니다.

 

-. componentDidUpdate() : DOM 렌더링 후, DOM 업데이트

 

-. componentWillUnmount() : 컴포넌트 제거를 할 때

 

적용된 코드는 아래와 같습니다.

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

  componentWillUnmount() {
    clearInterval(this.timerID);
  }

  tick() {
    this.setState({
      date: new Date()
    });
  }

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

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);
  출처 : https://ko.reactjs.org/docs/state-and-lifecycle.html

 


State 사용시 주의점

 

1. 직접 수정 X

// Wrong
this.state.comment = 'Hello';

// Correct
this.setState({comment: 'Hello'});

this.state를 지정할 수 있는 유일한 공간 : constructor

  constructor(props) {
    super(props);
    this.state = {comment: 'Hello'};
  }

2. 비동기적 특성으로 인한 오류발생

 

// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});

// Correct
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));

원인은 this.props 와 this.state가 비동기적 업데이트 되어, setState( another function(state,props) ) 형식으로 사용을 하여, 

==>

 

3. State 업데이트 병합됩니다. --> state로 선언된 값들은 하나의 object로 병합됩니다.

 

4. 컴포넌트는 각각 독립적 , State 값은 컴포넌트 내부에서 각각 독립적, state 는 캡슐화(소유,설정 컴포넌트 이외 접근 불가)

 

function App() {
  return (
    <div>
      <Clock />
      <Clock />
      <Clock />
    </div>
  );
}

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

위의 코드를 실행해보면, Clock(시계)함수가 독립적으로 3개 실행된것을 알 수 있으며, 각각의 Clock 함수내의 State 값들도 모두 독립적인 것을 알 수 있습니다.

 

 

 

반응형

+ Recent posts