😃

Vueエンジニアが使うReactが難しい

2023/12/27に公開
3

こんにちは!プロ雀士兼プログラマーのおおのです。
早いもので、初めてHello World!を目にしてもうすぐ2年。そろそろ駆け出しエンジニアを名乗れなくなりそうですが...今までNuxtを使用してVueのコードばかり書いてきた私が、新たにReactに挑戦してみたので、そこで苦労したことについて書いていこうと思います。

1.コンポーネントの書き方

まず最初に違うのは、コンポーネントをどう書くか。
Vueではtemplate、script、CSSを順に書いていく、シンプルな記述で1コンポーネントにまとめることができたのですが、Reactでは最初にscriptの記述をしたり、CSSフレームワークを使用する際の記述など、慣れるのに少々時間がかかりました。
初心者の私にはscriptの記述すら戸惑いだったのですが、ここは先人のお力を借りることでスムーズに溶け込むことができました。
(参考記事:Vue.jsエンジニアのためのReact入門)

CSSフレームワークに関してはTailwindCSSChakraUIなど、HTMLタグのように使用できるスタイルが主流となっており、細かいスタイルを当てることに慣れるには少々時間がかかりました。
私はChakraUIを使用しているのですが、慣れてしまえばすっきりするばかり。クラス名やインライン要素の種別分けなど、単純に省略できる記述が多く、Vueと比較してコードの記述量自体はかなり削減できました。

クラス名を当てる場合

<div class="flex-box">
 <p class="text-class">横並びの</p>
 <p>要素</p>
</div>

.flex-box{
    display:flex;

 .text-class {
   font-size:xs;
   color:darkGray;
  }
}

ChakraUIの場合

<Flex>
 <Text fontSize="xs" color="darkGray">横並びの</Text>
 <Text>要素</Text>
</Flex>

カスタムでクラスを編集することもできるため、プロジェクト内で共通するカラーやクラスをまとめることもできます。
(参考記事:Chakra Customize Theme)

2.状態管理

Reactを使用するにあたって、最もつまづくのが状態管理の方法だと思います。
Vueではmountedwatchなど、直感的にわかりやすいメソッドが多かったのですが、ReactではuseStateuseEffectを使用した値の管理がとにかく慣れなかったです。
最も苦戦したのはuseEffectにおける『依存配列』の使い方。ここを使いこなせなかった分、無限ループから抜け出せないことがありました(笑)。

※useEffectはレンダリングされるたびに発火する関数のため、依存配列を指定して値の変化を検知します。

export default function CountupComponent(){

    // countという状態変数と、その状態を更新する関数setCountをuseStateで宣言
  const [count, setCount] = useState(0);
  const [doubleCount, setDoubleCount] = useState(0);

  // countが変化するたびにuseEffect内のコードが実行される
  useEffect(() => {
    console.log(`Count changed: ${count}`);
    // countの変化に応じてdoubleCountを更新
    setDoubleCount(count * 2);
    // 依存配列の中にある値が変化したときだけuseEffectが実行される
  }, [count]); 
  
  const incrementCount = () => {
    setCount((prevCount) => prevCount + 1);
  };
 },);
 
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={incrementCount}>Increment Count</button>
    </div>
  );
 };
}

3.ライブラリの選定

今回はフォームを実装するにあたって、ページ間の値の保持のためにlittle-state-machineを使用してGlobal stateでの状態管理を行いました。
Vueで散々お世話になっていたVuexのstateと似たような使い方ができたので、取っ掛かりはしやすかったのですが、時間がかかったのは『little-state-machineを選定するまで』です。
Reactは技術や知見が豊富な分、要件を満たし、また数多くのGlobal state管理からバージョン、CSSフレームワーク、他のライブラリとの相性が良いライブラリを選定することに時間がかかりました。

文明の利器と対話しながら様々なサンプルコードを試しました

まとめ

見た目や使い方は違えど、やはり情報が豊富なので使い方を覚えてしまえば「Vueで書けたことができない」というようなことは無くなってきました。また、これは体感ですがVueで実装していた時よりも画面の動きが滑らかなになっているため、思い切ってReactに挑戦して良かったと思いました。レンダリングの影響なのか、CSSフレームワークの影響なのか不明ですが、原因が特定できた時にまた書こうと思います。

なんだか思った以上に初心者っぽい内容になってしまった上に、具体的なコードなどもあまり書けませんでしたが、同じようにこれからReactに挑戦する方に少しでも役立てれば幸いです。
次回は実装したことのある内容について、もっと具体的に紹介しようと思います。

O-KUN Tech Blog

Discussion

Honey32Honey32

細かいところで、意図から外れていたら恐縮ですが、

  const [count, setCount] = useState(0);
- const [doubleCount, setDoubleCount] = useState(0);
+ const doubleCount = count * 2;

- useEffect(() => {
-   setDoubleCount(count * 2);
- }, [count]); 

このように書くことができます。

元の書き方では「useEffect で count の変更を検知して、それをトリガーにして doubleCount を変更する」という考え方で「count の値が変わる→その状態(count は変更したが doubleCount が変わっていない中途半端な状態で)でレンダリングされる→useEffectによって、setDoubleCount を呼び出して doubleCount の値を更新する」という挙動になっていますが、

修正することで「setCount が呼び出されて再レンダリングされるたびに、上記のような中途半端な状態を経由せずに、最新の状態を表示する」という挙動になり、「doubleCount の値はつねに count の 2倍である」と考えることができ、状態をシンプルに分かりやすく捉えることができます。

https://qiita.com/honey32/items/58e56e407d4d87e294a4

このように、React で関数コンポーネントの関数の中に直書きした const doubleCount = ... のような代入文は、Vue だと computed() で書いた算出プロパティに相当します。

const doubeCount = computed(() => count.value * 2);
y_ohnoy_ohno

ご丁寧に参考記事までありがとうございます!
確かに、「わざわざuseEffectを使用する必要がない」という観点は大事ですね。

引き続きアウトプットしていきます!

rikutorikuto

ありがとうございます!
勉強になりました!