React.jsの宣言型と命令型の違いは?


97

最近、私はFacebookJavaScriptライブラリReact.jsの機能と使用方法について多くのことを研究しています。多くの場合、JavaScriptの世界の残りの部分にその違い2つのプログラミングスタイルといえばときdeclarativeimperativementionnedされています。

両方の違いは何ですか?


22
latentflip.com/imperative-vs-declarative Imperative programming: telling the "machine" how to do something, and as a result what you want to happen will happen. Declarative programming: telling the "machine"1 what you would like to happen, and let the computer figure out how to do it.
rickyduck

4
Tyler McGinnisはこれに関する長い記事をいくつかの良い例とともに書きまし
イアン・ダン

なぜコメントとして長い答えを追加するのですか?
アレックス

1
上記のリンクは正しいですが、リンクに含まれる末尾のスラッシュにより404が発生します。潜在的flip.com/imperative-vs-declarative
James Yoo

回答:


167

reactのような宣言型のスタイルでは、「このように見えるはずです」と言うことで、アプリケーションのフローと状態を制御できます。命令型のスタイルはそれを好転させ、「これがあなたがすべきことです」と言うことでアプリケーションを制御できるようにします。

宣言型の利点は、状態を表す実装の詳細にとらわれないことです。アプリケーションビューの一貫性を維持するための組織コンポーネントを委任しているため、状態について心配する必要があります。

フレームワークのメタファーのような執事がいると想像してみてください。そして、あなたは夕食を作りたいです。緊急の世界では、あなたは彼らに夕食の作り方を段階的に教えるでしょう。次の手順を提供する必要があります。

Go to the kitchen
Open fridge
Remove chicken from fridge
...
Bring food to the table

宣言型の世界では、あなたは単にあなたが望むものを説明するでしょう

I want dinner with chicken.

あなたの執事が鶏肉の作り方を知らなければ、宣言型で操作することはできません。バックボーンが特定のタスクを実行するために自分自身を変更する方法を知らない場合と同じように、そのタスクを実行するようにバックボーンに指示することはできません。Reactは、たとえば「鶏肉の作り方を知っている」ため、宣言型にすることができます。キッチンとのインターフェース方法しか知らないバックボーンと比較して。

状態を記述できると、バグの表面積が大幅に減少します。これは利点です。一方、状態の実装方法を委任または抽象化するため状況の発生方法の柔軟性が低下する可能性があります。


78

「いいね」ボタンなどの単純なUIコンポーネントを想像してみてください。タップすると、以前は灰色だった場合は青色に、以前は青色だった場合は灰色に変わります。

これを行うための必須の方法は次のとおりです。

if( user.likes() ) {
    if( hasBlue() ) {
        removeBlue();
        addGrey();
    } else {
        removeGrey();
        addBlue();
    }
}

基本的に、現在画面に表示されているものを確認し、前の状態からの変更を元に戻すなど、現在の状態で再描画するために必要なすべての変更を処理する必要があります。これが実際のシナリオでどれほど複雑になるか想像できます。

対照的に、宣言型アプローチは次のようになります。

if( this.state.liked ) {
    return <blueLike />;
} else {
    return <greyLike />;
}

宣言型アプローチは懸念事項を分離するため、この部分はUIが特定の状態でどのように見えるかを処理するだけでよく、したがって理解がはるかに簡単です。


21

これは素晴らしい例えです。

*必須の対応:駐車場の北口を出て左折します。バンガーターハイウェイ出口に着くまでI-15南に乗ります。Ikeaに行くように出口を右折します。直進し、最初の信号で右折します。次の信号を進み、次の信号を左折します。私の家は#298です。

宣言的応答:私の住所は298 West Immutable Alley、Draper Utah 84020 *です。

https://tylermcginnis.com/imperative-vs-declarative-programming/


18

React(宣言型)とJQuery(命令型)を比較して、違いを示すのが最善です。

Reactでは、render()以前のUI状態から新しいUI状態に移行する方法を気にすることなく、メソッドでUIの最終状態を記述するだけで済みます。例えば、

render() {
  const { price, volume } = this.state;
  const totalPrice = price * volume;

  return (
    <div>
      <Label value={price} className={price > 100 ? 'expensive' : 'cheap'} ... />
      <Label value={volume} className={volume > 1000 ? 'high' : 'low'} ... />
      <Label value={totalPrice} ... />
      ...
    </div>
  )
}

一方、JQueryでは、UIの状態を強制的に移行する必要があります。たとえば、ラベル要素を選択して、テキストとCSSを更新します。

updatePrice(price) {
  $("#price-label").val(price);
  $("#price-label").toggleClass('expansive', price > 100);
  $("#price-label").toggleClass('cheap', price < 100);

  // also remember to update UI depending on price 
  updateTotalPrice();
  ... 
}

updateVolume(volume) {
  $("#volume-label").val(volume);
  $("#volume-label").toggleClass('high', volume > 1000);
  $("#volume-label").toggleClass('low', volume < 1000);
  
  // also remember to update UI depending on volume
  updateTotalPrice();
  ... 
}

updateTotalPrice() {
  const totalPrice = price * volume;
  $("#total-price-label").val(totalPrice);
  ...
}

実際のシナリオでは、更新するUI要素に加えて、それらの属性(CSSスタイル、イベントリスナーなど)などがさらに多くなります。JQueryを使用してこれを強制的に行うと、複雑で面倒になります。UIの一部を更新するのを忘れたり、古いイベントハンドラーを削除するのを忘れたりするのは簡単です(メモリリークやハンドラーが複数回発生するため)。これはバグが発生する場所です。つまり、UIの状態とモデルの状態が不足しています。同期します。

モデルの状態を更新するだけでよく、ReactはUIとモデルの状態の同期を維持する責任があるため、状態が同期していないことはReactの宣言型アプローチでは発生しません。

  • フックの下で、Reactは命令型コードを使用して変更されたすべてのDOM要素を更新します。

宣言型プログラミングと命令型プログラミングの違いは何ですか?に関する私の答えも読むことができます。

PS:上記のjQueryの例から、すべてのDOM操作をupdateAll()メソッドに配置し、モデルの状態が変化するたびにそれを呼び出すと、UIが同期しなくなることはありません。正解です。これは事実上ReactがupdateAll()行うことです。唯一の違いは、jQueryが多くの不要なDOM操作を引き起こすことですが、Reactは仮想DOM差分アルゴリズムを使用して変更されたDOM要素のみを更新します。


6

命令型コードは、JavaScriptが各ステップをどのように実行するかを指示します。宣言型コードを使用して、JavaScriptに何をしたいかを伝え、JavaScriptに手順の実行を任せます。

Reactは宣言型です。なぜなら、必要なコードを記述し、Reactが宣言されたコードを取得し、JavaScript / DOMのすべての手順を実行して目的の結果を得ることができるからです。


5

命令型の世界での現実の類似点は、ビールのバーに入り、バーテンダーに次の指示を与えることです。

-棚からグラスを取り出します

-ドラフトの前にガラスを置きます

-ガラスがいっぱいになるまでハンドルを引き下げます

-グラスを渡してください。

代わりに、宣言型の世界では、「ビールをお願いします」と言うだけです。

ビールを求める宣言型アプローチは、バーテンダーがビールを提供する方法を知っていることを前提としています。これは、宣言型プログラミングが機能する方法の重要な側面です。

宣言型プログラミングでは、開発者は達成したいことだけを記述し、それを機能させるためにすべてのステップをリストする必要はありません。

Reactが宣言型アプローチを提供するという事実により、使いやすくなり、その結果、結果のコードは単純になり、多くの場合、バグが少なくなり、保守性が向上します。

Reactは宣言型パラダイムに従っており、DOMとの対話方法を指示する必要はありません。画面に表示したいものを宣言するだけで、Reactがその役割を果たします。


1

宣言型プログラミングはプログラミングパラダイムです…制御フローを記述せずに計算のロジックを表現します。

命令型プログラミングは、プログラムの状態を変更するステートメントを使用するプログラミングパラダイムです。

参照リンク:-https://codeburst.io/declarative-vs-imperative-programming-a8a7c93d9ad2


0

例えから始めましょう。2台の車があります。2台の車の中で、車内の温度を通常の室温〜72°Fにします。最初の(古い)車には、温度を制御するための2つのノブがあります(温度を制御するための1つのノブと、空気の流れを制御するための1つのノブ)。暑くなりすぎると、最初のノブを調整して温度を下げ、空気の流れを変える必要があります)、寒すぎる場合はその逆になります。これは必須の作業です!ノブは自分で管理する必要があります。2台目の(新しい)車では、温度を設定/宣言できます。つまり、車が72°Fに宣言/設定したことを知っている温度を調整するためにノブをいじる必要はありません。車はその状態に到達するために不可欠な作業を行います。

Reactは同じです。マークアップ/テンプレートと統計を宣言すると、ReactはDOMをアプリと同期させるために不可欠な作業を行います。

<button onClick={activateTeleporter}>Activate Teleporter</button>

を使用.addEventListener()してイベント処理を設定する代わりに、必要なものを宣言します。ボタンをクリックすると、activateTeleporter関数が実行されます。


-1
  • 宣言型では、すべてのビューを制御できます。(状態管理のように)
  • 命令型では、ビューの周囲を制御できます。($(this)のように)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.