[React] 리액트란? 리액트에 대하여

이호현·2022년 6월 13일
1

📚 React 📚

목록 보기
1/1
post-thumbnail

React(리액트)❓

  • Meta에서 개발한 오픈 소스 자바스크립트 라이브러리.

  • React는 UI 자바스크립트 라이브러리로써 싱글 페이지 애플리케이션(SPA)의 UI(User Interface)를 생성하는데 집중한 라이브러리이다.

  • 자바스크립트에 HTML을 포함하는 JSX(JavaScript XML)이라는 간단한 문법과
    단방향 데이터 바인딩(One-way Data Binding)을 사용하고 있다.

  • 가상 돔(Virtual DOM)이라는 개념을 사용하여 웹 애플리케이션의 퍼포먼스를 최적화한 라이브러리이다.

  • 페이지 전환 기능을 제공하지 않기 때문에, React를 사용하여 페이지 전환을 해야 한다면, react-router와 같은 추가적인 라이브러리를 사용해야 한다.

  • 선언형으로 상호작용이 많은 UI를 만들 때 생기는 어려움을 줄여준다. React는 데이터가 변경됨에 따라 적절한 컴포넌트만 효율적으로 갱신하고 렌더링하고, 선언형 뷰는 코드를 예측 가능하고 디버그 하기 쉽게 만들어 준다.


💡 SPA(Single Page Application)

서버에서 HTML을 생성하고 브라우저는 출력하기만 하는 전통적인 형태가 아니라,
서버가 하던 대부분의 작업을 브라우저에서 처리하는 웹 애플리케이션 개발 방법이다.

  • 즉, SPA에서는 서버가 처리하던 HTML 생성부터 내비게이션 처리, 사용자 인증에 따른 분기 처리, 검색 등을 JavaScript(또는 WebAssembly)로 처리하게 된다.

💡 단방향 데이터 바인딩(One-way Data Binding)

적절한 Event를 통해 데이터 흐름이 단방향으로 이루어지고(부모 -> 자식)
뷰가 바로 업데이트되지 않는다.


💡 Virtual DOM(가상 돔)

DOM(Document Object Model / 문서 객체 모델)

  • JavaScript에서 HTML의 문서에 접근하는 API를 뜻하는 용어로 DOM이 등장하였다.

  • DOM은 XML이나 HTML 문서에 접근하기 위한 일종의 인터페이스이다. 이 객체 모델은 문서 내의 모든 요소를 정의하고, 각각의 요소에 접근하는 방법을 제공한다.

  • 오늘날 JavaScript가 가장 널리 쓰이는 분야는 클라이언트용 인터페이스이다.
    이때 주로 JavaScript는 웹 브라우저에서 제공되는 DOM API를 사용하게 된다.

❗ 하지만 React는 Virtual DOM을 사용한다.

  • 서버와의 데이터 통신과는 별개로 DOM을 직접적으로 조작해야 하는 기존의 웹 화면 개발 방식과 달리, React는 DOM을 직접적으로 조작하지 않고 데이터가 변화할 때 변경사항이 적용된 Virtual DOM을 만든다.

  • 그다음 실제 DOM과 Virtual DOM의 차이점을 비교하고, 변경된 부분을 실제 DOM에 적용한다.

이 방식은 보여지는 데이터의 잦은 변경이 필요한 웹앱의 경우 성능을 크게 향상시킬 수 있다.

단, 데이터가 자주 변경되지 않는 비교적 정적인 웹 페이지에 이를 적용할 경우 오히려 성능면에서 손해를 볼 수 있다.


💡 JSX(JavaScript XML)

  • Javascript에 XML을 추가한 확장한 문법이다.
    React에서 HTML을 표현할 때, JSX를 사용한다.

  • 보기에는 HTML 같은 마크업 언어를 리터럴로 입력하는 것으로 보이는데, 빌드 시 Babel에 의해 자바스크립트로 변환된다.(Babel은 자바스크립트 컴파일러이다.)

  • 자바스크립트 코드를 HTML처럼 표현할 수 있기 때문에 용이한 개발이 가능하다.

HTML과 매우 흡사하지만, XML을 기반으로 한데다 Javascript 내부에서 사용하다 보니 차이점이 몇 가지 있다.

  • HTML 요소에 class 값을 정의할 때, 원래 HTML에서는
<p class="container"></p>

위와 같이 하면 되었지만, class라는 단어가 ECMAScript6(ES6)의 클래스 문법과 겹치는 예약어이기 때문에 대신에 className이라는 단어를 사용한다.


  • 마찬가지 이유로 루프문 예약어와 겹치는 forhtmlFor로 사용한다.

  • 요소에서 이벤트를 핸들링하는 onclick 등의 단어들은 onClick처럼 카멜 표기법(맨 처음 문자는 소문자로 표기 그 후 대문자)으로 표기해야 한다.

  • 기존의 HTML에서 주석은
<!-- 주석 -->

이렇게 했었지만 JSX에서는

{/*주석*/} 

으로 표현한다.


  • HTML Custom-Element는
<my-element>

와 같이 표기했지만 React의 Custom Element는

  <MyElement />

와 같이 Pascal Case(첫 단어를 대문자로 시작하는 표기법)로 표기한다. 닫는 태그에는 꼭 명시적으로 /> 표기를 해준다.


  • JSX 내부에서도 JS를 사용할 수 있다. {}로 불러온다. {console.log(this.props)} 같은 식이다.

💡 간단한 컴포넌트

React 컴포넌트는 render()라는 메서드를 구현하는데, 이것은 데이터를 입력받아 화면에 표시할 내용을 반환하는 역할을 한다.

class HelloMessage extends React.Component {
  render() {
    return (
      <div>
        Hello {this.props.name}
      </div>
    );
  }
}

ReactDOM.render(
  <HelloMessage name="Taylor" />,
  document.getElementById('hello-example')
);

컴포넌트로 전달된 데이터는 render() 안에서 this.props를 통해 접근할 수 있다.


💡 상태를 가지는 컴포넌트

컴포넌트는 this.props를 이용해 입력 데이터를 다루는 것 외에도 내부적인 상태 데이터를 가질 수 있습니다. 이는 this.state로 접근할 수 있다.

class Timer extends React.Component {
  constructor(props) {
    super(props);
    this.state = { seconds: 0 };
  }

  tick() {
    this.setState(state => ({
      seconds: state.seconds + 1
    }));
  }

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

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

  render() {
    return (
      <div>
        Seconds: {this.state.seconds}
      </div>
    );
  }
}

ReactDOM.render(
  <Timer />,
  document.getElementById('timer-example')
);

컴포넌트의 상태 데이터가 바뀌면 render()가 다시 호출되어 마크업이 갱신된다.


💡 애플리케이션

props와 state를 사용해서 간단한 Todo 애플리케이션을 만들 수 있다.

아래 코드에서는 state를 사용해 사용자가 입력한 텍스트와 할 일 목록을 관리한다.

class TodoApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = { items: [], text: '' };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  render() {
    return (
      <div>
        <h3>TODO</h3>
        <TodoList items={this.state.items} />
        <form onSubmit={this.handleSubmit}>
          <label htmlFor="new-todo">
            What needs to be done?
          </label>
          <input
            id="new-todo"
            onChange={this.handleChange}
            value={this.state.text}
          />
          <button>
            Add #{this.state.items.length + 1}
          </button>
        </form>
      </div>
    );
  }

  handleChange(e) {
    this.setState({ text: e.target.value });
  }

  handleSubmit(e) {
    e.preventDefault();
    if (this.state.text.length === 0) {
      return;
    }
    const newItem = {
      text: this.state.text,
      id: Date.now()
    };
    this.setState(state => ({
      items: state.items.concat(newItem),
      text: ''
    }));
  }
}

class TodoList extends React.Component {
  render() {
    return (
      <ul>
        {this.props.items.map(item => (
          <li key={item.id}>{item.text}</li>
        ))}
      </ul>
    );
  }
}

ReactDOM.render(
  <TodoApp />,
  document.getElementById('todos-example')
);

이벤트 핸들러들이 인라인으로 각각 존재하는 것처럼 보이지만,
실제로는 이벤트 위임을 통해 하나로 구현된다.


💡 외부 플러그인을 사용하는 컴포넌트

React는 유연하며 다른 라이브러리나 프레임워크를 함께 활용할 수 있다.

class MarkdownEditor extends React.Component {
  constructor(props) {
    super(props);
    this.md = new Remarkable();
    this.handleChange = this.handleChange.bind(this);
    this.state = { value: 'Hello, **world**!' };
  }

  handleChange(e) {
    this.setState({ value: e.target.value });
  }

  getRawMarkup() {
    return { __html: this.md.render(this.state.value) };
  }

  render() {
    return (
      <div className="MarkdownEditor">
        <h3>Input</h3>
        <label htmlFor="markdown-content">
          Enter some markdown
        </label>
        <textarea
          id="markdown-content"
          onChange={this.handleChange}
          defaultValue={this.state.value}
        />
        <h3>Output</h3>
        <div
          className="content"
          dangerouslySetInnerHTML={this.getRawMarkup()}
        />
      </div>
    );
  }
}

ReactDOM.render(
  <MarkdownEditor />,
  document.getElementById('markdown-example')
);

위 코드는 외부 마크다운 라이브러리인 remarkable을 사용해 <textarea>의 값을 실시간으로 변환한다.

이렇게 React에 대하여 알아보았습니다. 감사합니다 😊

참고

profile
# HoHo.log :)

0개의 댓글