概念や理論を学ぶと技術が理解しやすくなるという話

この記事はフラー Advent Calendar 2020における9日目の記事です。

8日目の記事はいのりこさんのBlock Kitを用いたSlack通知をGoで実装してみるでした。 定期的な癒しの提供は、なによりも優先されるべき事項だと思います。

概要

今年9月にフラー株式会社に入社し、Webフロントエンジニアとして、React + TypeScriptで開発を行っています。 入社後一ヶ月のオンボーディング期間に、Reduxの学習を行いました。 その中で、概念や理論を学ぶことで技術の理解がしやすくなるということを体験したので共有します。

よくわからなかったけど動かせていたRedux

Reduxについては、入社前に独学でReactを学んでいた時に読んでいた書籍で使用していたため、触れてはいました。 しかし、「Reduxとは」といった概念についての説明が乏しく、「こう書けば動く」ということがメインでした。 当時はあまり理解しておらず、「ReduxってReducerとかDispatchとか登場する要素が多くてよくわかんないなぁ」と思っていましたが、書籍内の例を真似して書けば動かせるからいいやと思っていました。

Reduxの基本概念

オンボーディング期間で、Reduxの公式チュートリアルを一通り進めていきました。 その冒頭でのReduxの概念とコンセプトについての説明があり、Reduxを組み込むとアプリケーションがどういう振る舞いをするのかがとてもわかりやすかったです。 f:id:kanterbury:20201208110310p:plain (出典:Redux Essentials, Part 1: Redux Overview and Concepts)

  • Stateがアプリケーションにおける特定の時点の状態を表す。
  • Viewが現時点でのStateに基づいてUIを描画する。
  • ユーザーの操作に応じてActionが発行される。現在のStateとActionの内容によって、Stateが更新される。
  • Stateが更新されたことによって、ViewがUIを更新する。

State, View, Actionがサイクルを描くのが、Reduxの基本的な動き方です。

immutability

Reduxの公式チュートリアルには以下の様に記載されています。(引用元

Redux expects that all state updates are done immutably.

「Reduxはすべての状態の更新が不変に行われることを期待しています」

Google翻訳

ここで語られているimmutabilityとはどういったものなのか、 公式チュートリアルでも紹介している以下のサイトにて勉強しました。

Immutability in React and Redux: The Complete Guide

immutabilityはオブジェクトが持つ性質を指します。オブジェクトがimmutableであるということは、そのオブジェクトは生成された後に値を変更されないことを指します。 JavaScriptはmutableな言語なので、生成されたオブジェクトの値を変更することが可能です。ですが、immutableに更新を行うことができます。

immutableじゃない例

addAgeは第一引数のオブジェクトに第二引数の数値をAgeプロパティとして追加したオブジェクトを返す関数ですが、引数として渡されたオブジェクトにプロパティの追加という変更が生じているのでimmutableではないです。

ちなみに、既存のオブジェクトに変化が生じることを副作用といいます。

let person = {
    name: "kanterbury",
    bloodType: "A"
}

// personオブジェクトに年齢を追加する関数
function addAge(person, num) {
    person.age = num // 既存のオブジェクトに変化が生じてしまっている
    return person
}

person = addAge(person, 18)

immutableな例

一方、こちらのaddAgeでは、引数のpersonオブジェクトにageプロパティを追加したオブジェクトnewPersonを生成し、それを返り値としています。 既存のpersonはあくまでコピー元として使用されただけなので、変化はありません。 personはaddAgeの返り値であるageが追加されたオブジェクトに置き換えられるので、immutableに更新が行われています。

let person = {
    name: "kanterbury",
    bloodType: "A" 
}

function addAge(person, num) {
    let newPerson = { //引数のpersonを元に、新しいオブジェクトを生成
        ...person,
        age: num
    }
    return newPerson
}

person = addAge(person, 18) //addAgeで生成された新しいオブジェクトに置き換える

この例のように、Reduxでも、アプリの状態を表すStateを更新する場合は、Stateの値を変更するのではなく、新しいStateを生成し、それに置き換えるという操作を行います。

上記の二点を踏まえると

ここまで説明したReduxのサイクル、そして、状態の更新はimmutableに行うことを踏まえると、ReduxがReducerやDispatchなどに分かれているのは、「状態更新の不変性を保った上で、サイクルを実現するため」だということが理解できました。

  • Action Creater: ユーザーの操作や入力に応じたActionを生成する。
  • Reducer: 現在のStateとActionの内容から、次のStateを生成する。現在のStateの内容を変更するのではなく、新しいStateを生成するのが役割。
  • Dispatch: Action Createrで生成されたActionをReducerに渡して、新しいStateを生成させる。Stateは生成された新しいものに置き換えられ、更新される。

まとめ

結局なにが言いたいのかというと、技術を学ぶ際には、その技術の概念、つまり、どんなことをどのように実現しようとしているのかを理解することが肝要ということです。

概念を理解すると、

→ 技術の構成要素それぞれにどういった役割があるのかがわかる

→ 役割がわかると、なにをさせればいいのかわかる

→ なにをさせればいいかわかると、どうコードを書けばいいのかわかるようになる

ということを身をもって体感しました。

実際の開発においても、既存のコードの真似をすればある程度動くものは書くことができますが、きちんと概念を理解した上で使用していきたいと思います。