React 자바스크립트 라이브러리 시작하기

게시 됨: 2022-02-16

WordPress 세계에서 시간을 보내면 아마도 Zac Gordon을 만났을 것입니다. Zac은 WordPress의 Javascript에 중점을 둔 열정적이고 매력적인 교사입니다. 그는 Matt Mullenweg의 "Learn Javascript Deeply"라는 문구를 차용하여 개인 슬로건으로 만들었습니다.

지난 몇 년 동안 Zac은 WordPress에서 Javascript를 사용하는 방법을 가르치는 데 중점을 둔 비디오 수업, 온라인 회의, 라이브 토크 및 팟캐스트를 제작했습니다.

"React Explained"라는 책을 Zac과 함께 작업하게 되어 기쁩니다. React는 WordPress 팀이 새로운 Gutenberg 편집기를 위해 선택한 라이브러리입니다. 그들은 혼자가 아닙니다. Drupal과 Magento도 React를 선택했습니다.

Zac은 Twitter의 @zgordon에서 글쓰기 진행 상황을 실시간 트윗하고 있습니다. 또한 OSTraining 팟캐스트에서 Zac이 React에 대해 이야기하는 것을 들을 수 있습니다.

이 책에서 발췌한 내용에서 Zac은 React와 몇 가지 주요 개념에 대한 높은 수준의 개요를 제공합니다.


리액트란?

기본적으로 React는 사용자 인터페이스를 구축하기 위한 라이브러리입니다.

React는 JavaScript 라이브러리이지만 React가 빌드하는 인터페이스는 불가지론적입니다.

빌드한 인터페이스가 브라우저, 서버, 기본 애플리케이션, 360 및 VR 환경에서도 작동하도록 하기 위해 여러 React 컴패니언 라이브러리가 존재합니다. 이 책에서 우리는 React로 구축한 인터페이스를 클라이언트 측 웹 사이트 및 애플리케이션에 추가하는 것을 관리하는 라이브러리인 ReactDOM으로 작업하는 데 중점을 둡니다. ReactDomServer, ReactNative 및 React360도 다른 환경에서 React 인터페이스를 사용하기 위해 탐색할 수 있는 라이브러리입니다.

인터페이스 구축을 위한 도우미 기능을 제공하는 것 외에도 React의 아키텍처를 사용하면 이벤트 처리, API 호출, 상태 관리, 인터페이스 업데이트 또는 더 복잡한 상호 작용과 관련된 인터페이스와의 상호 작용을 처리할 수 있습니다.

React는 일부 JavaScript 프레임워크만큼 많은 도우미 기능을 제공하지 않습니다. 이것이 우리가 프레임워크가 아니라 React 라이브러리를 호출하는 큰 부분입니다. React로 작업할 때 여전히 많은 바닐라 JavaScript를 작성해야 합니다.


React 구성 요소 아키텍처 설명

구성 요소는 독립적이고 재사용 가능한 코드 조각입니다(함수 또는 클래스를 통해 생성됨).

React는 사용자 인터페이스를 구축하고 코드를 구성하기 위해 구성 요소 아키텍처를 사용합니다. 간단한 React 앱의 기본 파일은 다음과 같습니다.

 // React 및 기타 구성 요소 가져오기
'반응'에서 React 가져오기;
'react-dom'에서 { 렌더 } 가져오기;
'./Header'에서 헤더 가져오기;
'./MainContent'에서 MainContent를 가져옵니다.
'./바닥글'에서 바닥글 가져오기;

함수 앱(){
  반품 (
    <div className="앱">
      <헤더 />
      <주요내용 />
      <바닥글 />
    </div>
 );
}

ReactDOM.render( <앱 />, document.getElementById("루트"));

여기에서 사용 중인 몇 가지 구성 요소를 볼 수 있습니다. <Header />, <MainContent /> 및 <Footer />는 모두 구성 요소입니다. App() 함수도 구성 요소이며 이 예제의 마지막 줄에서 ReactDOM 라이브러리와 ReactDOM.render() 메서드를 사용하여 빌드한 UI를 웹 페이지에 추가하는 것을 관리하는 방법을 볼 수 있습니다.

<Header />, <MainContent /> 및 <Footer /> 구성 요소를 자세히 살펴보면 HTML 마크업처럼 보이는 것뿐만 아니라 더 많은 구성 요소를 사용하는 것을 볼 수 있습니다.

 "반응"에서 React 가져오기;
"../Ad"에서 광고 가져오기;
"../assets/logo.svg"에서 로고 가져오기;

기본 함수 Header() 내보내기 {
반품 (
<header className="앱 헤더">
<광고 />
<img src={로고} className="앱 로고" alt="로고" />
<h1 className="app-title">사이트 이름</h1>
</헤더>
);
}

위의 이 <Header /> 구성 요소에서 우리는 <Ad />라는 또 다른 구성 요소를 가져오는 것을 볼 수 있습니다. 대부분의 React 애플리케이션에는 <App />, <Header /> 및 <Ad />에서 볼 수 있는 것처럼 여러 계층의 구성요소 중첩이 포함되어 있습니다.

우리는 또한 React 코드에서 HTML 요소의 사용을 봅니다. 이것은 JavaScript에서 직접 "HTML 마크업"을 작성할 수 있는 JSX라는 라이브러리 덕분에 가능합니다. React를 사용하여 사용자 인터페이스를 만들고 웹의 사용자 인터페이스에는 HTML 마크업이 포함되므로 UI ​​구성 요소 내에서 HTML과 같은 요소를 볼 수 있습니다. 우리는 이 책에서 JSX를 깊이 탐구할 것입니다.

React의 VR 라이브러리인 React 360을 사용하여 빌드된 간단한 React 앱의 일부 코드를 보면 우리가 호출하는 실제 구성 요소는 다르지만 구성 요소 아키텍처는 여전히 존재합니다.

 '반응'에서 React 가져오기;
가져오기 {
  텍스트,
  보다,
  VR 버튼,
} '반응-360'에서;

클래스 슬라이드쇼는 React.Component {를 확장합니다.
  // 간결함을 위해 제거된 코드
  반품 (
    <보기 스타일={styles.wrapper}>
      <보기 스타일={styles.controls}>
        <VrButton onClick={this.prevPhoto}>
          <텍스트>{'이전'}</Text>
        </Vr버튼>
        <VrButton onClick={this.nextPhoto}>
         <텍스트>{'다음'}</Text>
        </Vr버튼>
      <보기>
        <텍스트 스타일={styles.title}>{current.title}</Text>
      </보기>
    </보기>
  );
}

위의 코드는 일부 버튼과 텍스트가 오버레이된 360도 뷰의 여러 레이어를 만듭니다. 실제 코드가 완전히 이해되지 않을 수도 있지만 보기, 버튼 및 텍스트를 나타내는 여러 개의 중첩 구성 요소가 있다는 점은 분명해야 합니다.

이것은 서로 다른 매개변수를 전달하거나 React가 props라고 부르는 것을 전달하여 동일한 구성 요소가 다른 방식으로 재사용되는 방법을 볼 수 있기 때문에 좋은 예입니다. 데이터가 React 구성 요소를 통과하는 방법을 이해하는 것은 React로 빌드하는 데 사용되는 일반적인 구성 요소 아키텍처를 이해하는 데 중요합니다.


React 데이터 흐름 설명

React는 데이터가 애플리케이션을 통해 한 방향으로 아래로 전달되도록 구성 요소 계층에서 필요한 가장 높은 지점에서 데이터를 가져오고 설정하는 규칙을 따릅니다. 이 예제를 살펴보고 필요한 데이터 유형 중 일부를 상상해 봅시다. 다양한 구성 요소에 대한.

 함수 앱() {
  반품(
    <반응.조각>
      <헤더 />
      <내용 />
      <사이드바 />
      <바닥글 />
    </React.Fragment>
  );
}

사이트 이름과 같은 것은 <Header /> 및 <Footer /> 모두에서 사용할 수 있어야 합니다. 특정 페이지의 주요 콘텐츠는 <Content />로 전달되어야 합니다. 일부 추가 위젯 데이터는 <사이드바 />로 이동해야 할 수 있습니다.

 함수 앱() {
  const siteTitle = getSiteTitle();
  const 위젯 = getWidgets();
  const mainContent = getPageContent();
  반품(
    <반응.조각>
      <헤더 siteTitle={siteTitle} />
      <콘텐츠 mainContent={mainContent} />
      <사이드바 위젯={위젯} />
      <바닥글 siteTitle={siteTitle} />
    </React.Fragment>
  );
}

속성 이름을 만들고 값을 할당하는 이 규칙은 데이터를 구성 요소에 전달하는 방법입니다.

이제 <Header /> 및 <Footer />는 siteTitle에 액세스할 수 있고 <Content />는 mainContent에 액세스할 수 있으며 <Sidebar />는 필요한 위젯에 액세스할 수 있습니다.

중요한 참고 사항은 구성 요소에 데이터를 전달하는 이 패턴은 데이터를 한 수준만 전달한다는 것입니다. <Header /> 내부의 구성 요소는 siteTitle에 자동으로 액세스하지 않습니다.

 함수 헤더(소품) {
  반품(
    <헤더>
      <p>여기에서 {props.siteTitle}을(를) 볼 수 있습니다.</p>
      <PageHeader siteTitle={props.siteTitle} />
      <페이지 서브헤더 />
    </헤더>
  );
}

여기에서 <Header /> 내부에서 props.siteTitle을 호출하고 전달한 값에 액세스할 수 있음을 알 수 있습니다. 그러나 <PageHeader /> 구성 요소 내에서 siteTitle에 액세스하려면 해당 정보도 수동으로 전달해야 합니다.

구성 요소가 값을 소품으로 받으면 수정해서는 안 됩니다. Props는 변경할 수 없는 데이터로 구성 요소 트리를 통과해야 합니다. 이것은 prop을 참조하는 모든 구성 요소가 자식 구성 요소의 부모와 동일한 값을 참조하도록 합니다.

prop의 값은 원래 prop의 값을 설정하고 컴포넌트 트리를 통해 전달하기 시작한 컴포넌트에서만 변경되어야 합니다. 위의 예제 코드에서 <App /> 구성 요소는 siteTitle의 값을 변경할 수 있지만 <Header /> 또는 <PageHeader /> 구성 요소는 변경해서는 안 됩니다.

React 앱에서 동적 데이터가 업데이트되는 흐름을 이해하려면 상태 및 이벤트 핸들러를 props로 전달할 수 있는 방법에 대한 논의가 필요합니다.


React 구성 요소 상태 설명

우리가 배운 것처럼 데이터는 props로 구성 요소를 통해 변경되지 않은 상태로 흐릅니다. 데이터는 모든 자식 구성 요소가 props로 필요한 정보를 전달하는 데 필요한 트리의 가장 높은 구성 요소에 설정됩니다.

어떤 경우에는 이 데이터가 한 번 수신되고 변경할 필요가 없습니다. 대부분의 경우 해당 데이터는 동적 상태를 유지해야 하고 주어진 시간에 업데이트할 수 있어야 하며 해당 업데이트가 모든 하위 구성 요소에 반영되도록 해야 합니다.

React에서 변경되는 데이터를 추적하기 위해 React 상태 객체와 상태 값을 업데이트하는 도우미 함수 세트가 있습니다.

다음은 자체적으로 업데이트되는 카운터의 예입니다. 카운터 값은 이 구성 요소 내에서 동적인 값이므로 언제 상태에 의존해야 하는지에 대한 좋은 예가 됩니다. 상태가 있는 구성 요소를 만들려면 함수가 아닌 JavaScript 클래스를 사용해야 합니다.

 클래스 카운터 확장 구성 요소 {
  상태= {
    카운터:0
  };

  핸들 수 = () => {
    this.setState({
      카운터: this.state.counter + 1
    });
  };

  렌더링() {
    반품 (
      <div>
        <h1>{this.state.counter}</h1>
        <button onClick={this.handleCount}>카운트 업!!</button>
      </div>
    );
  }
}

이제 이 상태가 이 구성 요소로만 범위가 지정된다는 점에 유의하는 것이 중요합니다. counter의 state 값은 자식 또는 부모 구성 요소에서 사용할 수 없습니다.

따라서 아래와 같은 더 복잡한 예제에서는 counter down 값을 prop으로 자식 요소에 전달해야 합니다.

 클래스 카운터 확장 구성 요소 {
  상태= {
    카운트:0
  };

  핸들 수 = () => {
    this.setState({
      개수: this.state.count + 1
    });
  };

  렌더링() {
    반품 (
      <div>
        <페이지 헤더 개수={this.state.count} />
        <button onClick={this.handleCount}>카운트 업!!</button>
      </div>
    );
  }
}

<PageHeader /> count prop은 <Counter /> 구성 요소의 상태를 업데이트할 때마다 업데이트됩니다.

 기능 페이지 헤더(소품) {
  반환 <h1>{props.count}</h1>; 
}

이 접근 방식의 좋은 점은 상태가 업데이트될 때마다 prop 값이 state로 설정된 모든 자식 구성 요소에 새 값이 자동으로 전달된다는 것입니다.

이를 통해 동적 데이터에 대한 단일 진실 지점을 가질 수 있습니다. 진실의 근원은 단일 구성 요소에서 관리되는 상태의 값입니다. 자식 구성 요소에서 이 값의 모든 인스턴스는 이 구성 요소 외부에서 변경되어서는 안 되는 props로 수신된 변경할 수 없는 값입니다.

계층 구조에서 이 구성 요소 위에 나타나는 구성 요소는 props를 통해서만 전달되기 때문에 이 데이터에 액세스할 수 없습니다. 데이터가 필요한 모든 사람이 데이터를 사용할 수 있도록 계층의 상위 구성 요소에서 상태를 설정하고 관리하려고 하는 이유를 다시 한 번 알 수 있습니다.

앱을 통해 수많은 소품을 수동으로 전달할 필요가 없는 고차 구성 요소 및 컨텍스트 API와 같은 몇 가지 다른 아키텍처 패턴이 있습니다. 우리는 나중에 이것들을 더 깊이 탐구할 것입니다. 지금으로서는 지름길을 시작하기 전에 일반적으로 어떻게 작동하는지에 대한 높은 수준의 개요를 이해하고 있는지 확인하고 싶습니다.

React에서 컴포넌트 상태 업데이트하기

이제 자식 구성 요소에서 상태를 업데이트하도록 트리거하려는 경우 어떻게 됩니까?

예를 들어, 위의 예에서 우리의 메인 <Counter /> 구성 요소에 하드 코딩된 버튼이 아닌 <Button /> 구성 요소를 원한다고 상상해 보십시오. 이것은 실제로 복잡한 앱에서 매우 일반적입니다.

이에 대한 해결책은 React 세계에서 setState를 소품으로 사용하여 상태를 업데이트하는 이벤트 핸들러 함수를 전달하는 것입니다. 그런 다음 모든 하위 구성 요소에서 호출할 수 있지만 상태를 설정하고 업데이트할 수 있는 원래 구성 요소에서 작업이 수행됩니다. 이에 대한 다른 패턴도 존재하지만 이 접근 방식이 가장 기본입니다.

매개변수로 함수를 전달하는 것에 익숙하지 않다면 완전히 유효한 바닐라 JavaScript입니다.

상태가 업데이트되면 props를 통해 구성 요소 계층을 통해 전달됩니다.

다음은 그것이 어떻게 생겼는지에 대한 예입니다.

 클래스 카운터 확장 구성 요소 {
  상태= {
    카운트:0
  };

  핸들 수 = () => {
    this.setState({
      개수: this.state.count + 1
    });
  };

  렌더링() {
    반품 (
      <div>
        <페이지 헤더 개수={this.state.count} />
        <버튼 핸들 개수={this.handleCount} />        
      </div>
    );
  }
}

기능 PageHeader( 소품 ) { 
  반품( 
    <h1>{props.count}</h1>
 ); 
}

기능 버튼( 소품 ) {
  반품(
    <button onClick={props.handleCount}>카운트 업!!</button>  
  );
}

여기에서 React가 데이터 흐름을 처리하는 방법에 대한 간단한 예를 볼 수 있습니다. 데이터에 대한 단일 진실 지점이 있습니다. 단일 구성 요소에서 설정되고 업데이트된 상태에 존재합니다. 데이터는 props를 통해 중첩된 구성 요소 트리를 통해 단방향으로 전달됩니다.

상태가 원래 설정된 위치가 아닌 다른 구성 요소에서 업데이트되어야 하는 경우 이벤트 핸들러를 필요한 하위 구성 요소에 소품으로 전달할 수 있습니다. 이렇게 하면 자식 구성 요소가 변경을 트리거하더라도 원래 구성 요소의 상위에서 변경 사항이 발생하기 때문에 데이터를 변경할 수 없고 한 방향으로 흐릅니다.

아래와 같이 상태에서 무언가에 prop 값을 할당하면 상태가 변경될 때마다 해당 prop 값이 자동으로 업데이트됩니다.

 <PageHeader 카운터={this.state.count} />

해당 prop 값을 참조하는 다른 모든 자식 구성 요소도 자동으로 업데이트를 받습니다. 이것이 React의 데이터 흐름의 아름다움입니다.

과거에 JavaScript에서 이와 같은 문제에 어떻게 접근했는지에 따라 익숙해지는 데 시간이 조금 걸릴 수 있습니다. 그러나 이것은 우리가 React를 더 깊이 설명할 수 있는 좋은 출발점이 되어야 합니다.