ReactJavascriptライブラリ入門

公開: 2022-02-16

WordPressの世界で時間を過ごすなら、おそらくZacGordonに出くわしたことでしょう。 Zacは、WordPressのJavascriptに焦点を当てている熱心で魅力的な教師です。 彼はMattMullenwegから「LearnJavascriptDeeply」というフレーズを借りて、それを彼の個人的なスローガンにしました。

過去数年間、Zacは、WordPressでJavascriptを使用する方法を教えることに焦点を当てたビデオクラス、オンライン会議、ライブトーク、およびポッドキャストを作成してきました。

「ReactExplained」という本でザックと協力していることを嬉しく思います。 Reactは、WordPressチームが新しいGutenbergエディター用に選択したライブラリです。 彼らだけではありません-DrupalとMagentoの両方がReactを選択しました。

ザックはツイッターの@zgordonで彼の執筆の進捗状況をライブツイートしています。 ZacがOSTrainingポッドキャストでReactについて話すのを聞くこともできます。

この本からの抜粋では、ZacがReactの概要といくつかの重要な概念を示しています。


Reactとは何ですか?

箱から出して、Reactはユーザーインターフェースを構築するためのライブラリです。

ReactはJavaScriptライブラリですが、Reactが構築するインターフェースは不可知論者です。

構築したインターフェースをブラウザー、サーバー、ネイティブアプリケーション、さらには360およびVR環境で機能させるために、いくつかのReactコンパニオンライブラリが存在します。 この本では、Reactで構築したインターフェースをクライアント側のWebサイトやアプリケーションに追加することを管理するライブラリであるReactDOMの操作に焦点を当てています。 ReactDomServer、ReactNative、およびReact360は、他の環境でReactインターフェースを使用するために探索したいライブラリーでもあります。

インターフェースを構築するためのヘルパー関数を提供することに加えて、Reactのアーキテクチャーでは、イベント処理、API呼び出し、状態管理、インターフェースの更新、またはより複雑なインタラクションを含むかどうかにかかわらず、インターフェースとのインタラクションを処理できます。

Reactは、一部のJavaScriptフレームワークほど多くのヘルパー関数を提供しません。 これが、Reactをフレームワークではなくライブラリと呼ぶ理由の大部分です。 Reactを操作するときは、まだたくさんのバニラJavaScriptを書く必要があります。


Reactコンポーネントアーキテクチャの説明

コンポーネントは、独立した再利用可能なコード(関数またはクラスを介して作成されたもの)です。

Reactは、コンポーネントアーキテクチャを使用して、ユーザーインターフェイスを構築し、コードを整理します。 単純なReactアプリのメインファイルは次のようになります。

 // Reactおよびその他のコンポーネントをインポートします
'react'からReactをインポートします。
import {render} from'react-dom ';
'./Header'からヘッダーをインポートします。
'./MainContent'からMainContentをインポートします;
'./Footer'からフッターをインポートします。

関数App(){
  戻る (
    <div className = "app">
      <ヘッダー/>
      <MainContent />
      <フッター/>
    </ div>
 );
}

ReactDOM.render(<App />、document.getElementById( "root"));

ここで、使用中のいくつかのコンポーネントを確認できます。 <Header />、<MainContent />、および<Footer />はすべてコンポーネントです。 App()関数もコンポーネントであり、この例の最後の行で、ReactDOMライブラリとReactDOM.render()メソッドを使用して、作成したUIをWebページに追加する方法を確認できます。

<Header />、<MainContent />、および<Footer />コンポーネントの内部を掘り下げると、HTMLマークアップのように見えるだけでなく、より多くのコンポーネントが使用される可能性があります。

 「react」からReactをインポートします。
「../Ad」から広告をインポートします。
「../assets/logo.svg」からロゴをインポートします。

デフォルトの関数Header()をエクスポートします{
戻る (
<header className = "app-header">
<広告/>
<img src = {logo} className = "app-logo" alt = "logo" />
<h1className = "app-title">サイト名</ h1>
</ header>
);
}

上記のこの<Header />コンポーネントでは、<Ad />と呼ばれるさらに別のコンポーネントをプルしていることがわかります。 ほとんどのReactアプリケーションには、<App />、<Header />、および<Ad />で見られるように、コンポーネントのネストのいくつかのレイヤーが含まれています。

また、ReactコードでのHTML要素の使用も確認できます。 これは、JavaScriptで直接「HTMLマークアップ」を記述できるJSXと呼ばれるライブラリのおかげで可能になります。 Reactを使用してユーザーインターフェイスを作成しており、Web上のユーザーインターフェイスにはHTMLマークアップが含まれているため、UIコンポーネント内にHTMLのような要素が表示されるのは理にかなっています。 この本では、JSXについて詳しく説明します。

ReactのVRライブラリであるReact360を使用して構築された単純なReactアプリのコードを見ると、実際に呼び出すコンポーネントは異なりますが、コンポーネントのアーキテクチャはまだ存在しています。

 'react'からReactをインポートします。
輸入 {
  文章、
  意見、
  VrButton、
} from'react-360 ';

クラスSlideshowはReact.Componentを拡張します{
  //簡潔にするためにコードを削除
  戻る (
    <View style = {styles.wrapper}>
      <View style = {styles.controls}>
        <VrButton onClick = {this.prevPhoto}>
          <テキスト> {'前へ'} </テキスト>
        </ VrButton>
        <VrButton onClick = {this.nextPhoto}>
         <テキスト> {'次へ'} </テキスト>
        </ VrButton>
      <表示>
        <Text style = {styles.title}> {current.title} </ Text>
      </表示>
    </表示>
  );
}

上記のコードは、いくつかのボタンとテキストがオーバーレイされた360ビューの複数のレイヤーを作成します。 実際のコードは完全には意味をなさないかもしれませんが、ビュー、ボタン、テキストを表すネストされたコンポーネントがいくつかあることは明らかです。

これは良い例です。なぜなら、同じコンポーネントに異なるパラメーターを渡すことで、同じコンポーネントがさまざまな方法で再利用される方法や、Reactが小道具と呼ぶものを確認できるからです。 データがReactコンポーネントをどのように通過するかを理解することは、Reactで構築するために使用される典型的なコンポーネントアーキテクチャを理解するために重要です。


Reactデータフローの説明

Reactは、データがアプリケーションを一方向に通過するためにコンポーネント階層で必要な最高点でデータを取得および設定するという規則に従います。この例を見て、必要なデータの種類のいくつかを想像してみましょう。さまざまなコンポーネント用。

 関数App(){
  戻る(
    <React.Fragment>
      <ヘッダー/>
      <コンテンツ/>
      <サイドバー/>
      <フッター/>
    </React.Fragment>
  );
}

<Header />と<Footer />の両方で、サイトの名前のようなものを使用できるようにする必要がある場合があります。 特定のページのメインコンテンツを<Content />に渡す必要があります。 追加のウィジェットデータの一部は、<サイドバー/>に移動する必要がある場合があります。

 関数App(){
  const siteTitle = getSiteTitle();
  const widgets = getWidgets();
  const mainContent = getPageContent();
  戻る(
    <React.Fragment>
      <Header siteTitle = {siteTitle} />
      <Content mainContent = {mainContent} />
      <サイドバーウィジェット= {ウィジェット} />
      <フッターsiteTitle = {siteTitle} />
    </React.Fragment>
  );
}

属性名を作成して値を割り当てるというこの規則は、データをコンポーネントに渡す方法です。

これで、<Header />と<Footer />がsiteTitleにアクセスし、<Content />がmainContentにアクセスし、<Sidebar />が必要なウィジェットにアクセスできるようになりました。

重要な注意点は、データをコンポーネントに渡すこのパターンでは、データが1レベルしか渡されないことです。 <Header />内のコンポーネントは自動的にsiteTitleにアクセスしません。

 関数ヘッダー(小道具){
  戻る(
    <ヘッダー>
      <p>ここで{props.siteTitle}を見ることができます。</ p>
      <PageHeader siteTitle = {props.siteTitle} />
      <PageSubHeader />
    </ header>
  );
}

ここで、<Header />内でprops.siteTitleを呼び出して、渡した値にアクセスできることがわかります。 ただし、<PageHeader />コンポーネント内のsiteTitleにアクセスしたい場合は、その情報も手動で渡す必要があります。

コンポーネントが小道具として値を受け取った場合、それを変更してはなりません。 小道具は、不変のデータとしてコンポーネントツリーを通過する必要があります。 これにより、propを参照するすべてのコンポーネントが、子コンポーネントの親と同じ値を参照するようになります。

小道具の値は、元々小道具の値を設定し、それをコンポーネントツリーに渡し始めたコンポーネントでのみ変更する必要があります。 上記のサンプルコードでは、<App />コンポーネントはsiteTitleの値を変更できますが、<Header />または<PageHeader />コンポーネントは変更しないでください。

Reactアプリで動的データがどのように更新されるかのフローを理解するには、状態と、イベントハンドラーを小道具として渡す方法について説明します。


Reactコンポーネントの状態の説明

私たちが学んだように、データは小道具としてコンポーネントを介して変更されずに流れます。 データは、すべての子コンポーネントに必要な情報が小道具として渡されるために必要なツリーの最上位のコンポーネントに設定されます。

場合によっては、このデータは一度受信され、変更する必要はありません。 ただし、多くの場合、そのデータは動的であり、いつでも更新でき、その更新がすべての子コンポーネントに反映される必要があります。

Reactで変更されるデータを追跡するために、React状態オブジェクトと状態値を更新するための一連のヘルパー関数があります。

これは、それ自体を更新するカウンターの例です。 カウンターの値は、このコンポーネント内で動的な値であるため、状態に依存するタイミングの良い例になります。 状態のあるコンポーネントを作成するには、関数ではなくJavaScriptクラスを使用する必要があることに注意してください。

 クラスCounterextends Component {
  状態= {
    カウンター:0
  };

  handleCount =()=> {
    this.setState({
      カウンター:this.state.counter + 1
    });
  };

  与える() {
    戻る (
      <div>
        <h1> {this.state.counter} </ h1>
        <buttononClick = {this.handleCount}>カウントアップ!! </ button>
      </ div>
    );
  }
}

ここで、この状態はこのコンポーネントのみにスコープされていることに注意することが重要です。 カウンターの状態の値は、子コンポーネントまたは親コンポーネントでは使用できません。

したがって、以下のようなより複雑な例の例では、counterの値を小道具として子要素に渡す必要があります。

 クラスCounterextends Component {
  状態= {
    カウント:0
  };

  handleCount =()=> {
    this.setState({
      カウント:this.state.count + 1
    });
  };

  与える() {
    戻る (
      <div>
        <PageHeader count = {this.state.count} />
        <buttononClick = {this.handleCount}>カウントアップ!! </ button>
      </ div>
    );
  }
}

<PageHeader />カウントプロップは、<Counter />コンポーネントの状態を更新するたびに更新されます

関数PageHeader(props){
  <h1> {props.count} </ h1>を返します。 
}

このアプローチの良いところは、状態が更新されるたびに、propの値がstateに設定された新しい値が子コンポーネントに自動的に渡されることです。

これにより、動的データの信頼できる唯一の情報源を得ることができます。 信頼できる情報源は、単一のコンポーネントから管理される状態の値です。 子コンポーネントのこの値のすべてのインスタンスは、このコンポーネントの外部で変更してはならない小道具として受け取られる不変の値です。

階層内でこのコンポーネントの上に表示されるコンポーネントは、小道具を介してのみ渡されるため、このデータにアクセスできません。 階層の上位にあるコンポーネントから状態を設定および管理して、データを必要とするすべての人がデータを利用できるようにする理由をもう一度確認します。

高次コンポーネントやコンテキストAPIなど、他にもいくつかのアーキテクチャパターンがあり、アプリを介して大量の小道具を手動で渡す必要がありません。 これらについては、後で詳しく説明します。 今のところ、ショートカットを取り始める前に、物事が一般的にどのように機能するかについてのこの高レベルの概要を理解していることを確認したいと思います。

Reactでのコンポーネントの状態の更新

さて、子コンポーネントから状態が更新されるようにトリガーしたい場合はどうなりますか?

たとえば、上記の例で、メインの<Counter />コンポーネントにハードコードされたボタンではなく<Button />コンポーネントが必要だったと想像してみてください。 これは実際、複雑なアプリでは非常に一般的です。

これに対する解決策は、Reactの世界では、setStateを小道具として使用して状態を更新するイベントハンドラー関数を渡すことです。 次に、任意の子コンポーネントから呼び出すことができますが、アクションは、状態を設定し、それを更新する機能を持つ元のコンポーネントで実行されます。 これには他のパターンもありますが、このアプローチが最も基本的です。

関数をパラメーターとして渡すことに慣れていない場合は、完全に有効なバニラJavaScriptです。

状態が更新されると、小道具を介してコンポーネント階層を介して渡されます。

これがどのように見えるかの例です。

 クラスCounterextends Component {
  状態= {
    カウント:0
  };

  handleCount =()=> {
    this.setState({
      カウント:this.state.count + 1
    });
  };

  与える() {
    戻る (
      <div>
        <PageHeader count = {this.state.count} />
        <ボタンhandleCount = {this.handleCount} />        
      </ div>
    );
  }
}

function PageHeader(props){ 
  戻る( 
    <h1> {props.count} </ h1>
 ); 
}

関数ボタン(小道具){
  戻る(
    <button onClick = {props.handleCount}>カウントアップ!! </ button>  
  );
}

ここでは、Reactがデータフローを処理する方法の簡単な例を見ることができます。 データには信頼できる唯一の情報源があります。 これは状態セットに存在し、単一のコンポーネントから更新されます。 データは、小道具を介してネストされたコンポーネントツリーを介して一方向に渡されます。

状態を最初に設定された場所以外のコンポーネントから更新する必要がある場合は、イベントハンドラーを必要な子コンポーネントに小道具として渡すことができます。 これにより、データが不変で一方向に流れるようになります。これは、子コンポーネントが変更をトリガーした場合でも、その変更は元のコンポーネントの上位で行われるためです。

以下のように、小道具の値を状態から何かに割り当てると、その小道具の値は、状態が変化するたびに自動的に更新されます。

 <PageHeader counter = {this.state.count} />

そのprop値を参照する他の子コンポーネントも、自動的に更新を受け取ります。 これがReactのデータフローの美しさです。

これは、過去にJavaScriptでこのような問題にどのように取り組んだかによっては、慣れるまでに少し時間がかかる場合があります。 ただし、これはすべて、Reactの説明をより深く掘り下げるための良い出発点として役立つはずです。