63
45

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Reactの思想を理解してリファクタする

Last updated at Posted at 2022-07-28

抱えていた疑問

propsの理解やcomponentの作り方、hooks、ES2015以降のjsの書き方はわかる。
でも、React的に最適なリファクタは何?ということが疑問でした。
Reactをより理解し、疑問を解消できればと思います。

Reactは宣言的である。

答えを求めてReactのTOPページへやってきました。
そこには宣言的という言葉が目立つところに存在します。


Declarative views make your code more predictable and easier to debug.

宣言型ビューは、コードをより予測しやすくし、デバッグを容易にします。
命令的ではなく、宣言的にコードを書いていくことを思想としているようです。

宣言的?命令的?それは何?

命令的とは何か

何をするか?を1つ1つ記述(命令)していくこと。

/*
bodyを取ってくる
h1を生成する
h1に"hello"と入れる
bodyにh1を入れる
*/
const body = document.body;
const h1 = document.createElement('h1');
h1.innerText = 'ようこそ!';
body.appendChild(h1);
特徴
  • カスタム性が高い
  • コードが多くて実装が大変
  • 見通しが良くない
  • 変更も大変

宣言的とは何か

欲しい結果だけを要求する。

 <body>
   <h1>ようこそ!</h1>
 </body>
特徴
  • 細かいやり方は(コンピューターやライブラリに)任せる
  • 実装がシンプル
  • 変更も容易

宣言的、命令的の例:コーヒーの淹れ方

より宣言的に進化するReact

クラスコンポーネントから関数コンポーネントへ

クラスコンポーネントとは、propsを用いて自身の描画内容を決定するという仕組みがあるだけでも、最低限の宣言的UIであるといえます。
しかし、hook(フック)の登場により、より宣言度合いを高めました。

一昔前のクラスコンポーネントです。
「component作成時に状態(この場合count)を0に初期化しなさい」という命令的なコードを含んでいます。

class Counter extends React.Component {
   constructor(props) {
      super(props);
      this.state = {count:0}
   }
   render() {
     return {
        <button onClick={() => this.setState(state => ({ count: state.count +1 }))}>
          {count}
        </button>
      }
   }
}

次は関数コンポーネントの例です
React16.8から使えるようになったhook(フック)の機能であるuseStateを呼び出し、状態を初期化します。
このAPIを呼びだせば、あとはReactがよしなにやってくれるという点で、宣言的度合いが増しています。
(記述もスリムになりましたネ)

import { useState } from 'react'

const Counter = () => {
  const [count, setCount] = useState(0);
  return (
    <button onClick={()=> setCount(c => c + 1)}>
      {count}
    </button>
  )
}

(ボタンを)クリックしたらcountを1つ増やしなさい という命令をHTML部分に含んでしまいました。
より宣言的にするため、関数は外へ出すリファクタを行う方が良さそうです。


+ const addCount = () => {
+   setCount(c => c + 1)
+ }

- <button onClick={()=> setCount(c => c + 1)}>
+ <button onClick={addCount}>

React18の新機能も宣言的

Suspense(待機処理)の登場

React18で導入されたSuspenseは、従来命令的だった待機処理を宣言的に書くことができます。

//今までの待機処理
const App = () => {
  return <MyComponent />
}
const MyComponent = () => {
  // APIから情報を取得(SWRライブラリを使用)
  const { loading , data } = useSWR(URL, getData)

  if (loading) {
    return <Loading />
  }
  return <p>私の名前は{data.name}です</p>
}

今まではif (loading)を使用し、待機中のコンポーネントを出し分けていました。
React18では if (loading) 部分をSuspenseがよしなに行ってくれることで、より宣言的になりました。

//Suspense使用
const App = () => {
  return (
    <Suspense fallback={<Loading />}>
      <MyComponent />
    </Suspense>
  )
}
const MyComponent = () => {
  const { data } = useSWR(URL, getData)
  return <p>私の名前は{data.name}です</p>
}

Reactの思想を理解してリファクタする

Reactの進化、新機能からも見て取れるよう、宣言的であることはブレていません。
そんなReactに対し、命令的 、場当たり的な実装をするということはReactの思想に反するように思えます。
(useRefで初期化したものをuseEffect内で判定処理に使うなど)
今は問題なく動くかもしれませんが、今後のバージョンアップ(破壊的変更)に耐えることができない,,,こともありえます。
その時、バージョンアップのために多くの改修が予想されます。

Reactは宣言的であるという思想を理解した上で実装、リファクタを行うことが大切だとわかりました。


自分の考えが絶対正しいとは思っていません!!
ぜひぜひコメントをお願いします!!

63
45
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
63
45

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?