LoginSignup
61
79

【初心者向け】Reactでよく使うJavaScriptのメソッドや構文13選とReact Hooks(プチ紹介)

Last updated at Posted at 2024-05-26

はじめに

最近、ひょんなことから初学者向けのReactアプリをレベル別に10個くらい開発しながら、ハンズオンで学べる教材的なものを作成する機会があり、それを実施する前に最低限理解していたら学習がスムーズに進むだろうと思われるものをまとめました。

また、予習編としてReact専用で使用されるものも簡単に紹介します。

ちなみに、すでに「基本編くらいわかるわ!」って方は予習編はみなくていいので、以下のリファレンスのチュートリアルをやっちゃってください。Udemyなんかでもいいと思いますのでどんどん手を動かすフェーズに入っていきましょう。

https://ja.react.dev/
スクリーンショット 2024-05-27 7.46.05.png

基本編(JavaScript)

  1. mapメソッド

    • 配列内の全ての要素に対して関数を適用し、新しい配列を作成します。
    const items = ['apple', 'banana', 'cherry'];
    const listItems = items.map(item => <li key={item}>{item}</li>);
    
    • items配列の各要素を<li>タグで囲み、listItemsという新しい配列を作成します。
    • 特にこのmap()はアホみたいにReactでは出現しますので、もう覚えちゃいましょう。一番出てくるのは以下のような形です。
    const todos = [
      { id: 1, text: 'Learn JavaScript', completed: false },
      { id: 2, text: 'Build a Todo App', completed: false },
      { id: 3, text: 'Master React', completed: false }
    ];
    
    function TodoList() {
      return (
        <ul className=''> // スタイリングは省略
          {todos.map((todo) => (
            <li key={todo.id}>
              {todo.text}
            </li>
          ))}
        </ul>
      );
    }
    
    export default TodoList;
    
    

  1. filterメソッド

    • 配列内の要素をフィルタリングして、新しい配列を作成します。
    • こちらもよく使用されます。map()と形が似ていて初学者の方は混乱するかもしれませんが違いを理解しておきましょう。
    const numbers = [1, 2, 3, 4, 5];
    const evenNumbers = numbers.filter(number => number % 2 === 0);
    
    • numbers配列から偶数だけを含む新しい配列evenNumbersを作成します。

    例えばTodoなんかの削除機能がわかりやすい例かと思います。以下のように、対象のtodoのidと一致しないidをフィルタリングしてあげれば引数で渡されたidのtodoは除外された配列が作成されて、delete機能が完成します。

    const [todo, setTodo] = useState<{ text: string; isComplete: boolean }[]>([]);
    // 省略
    const deleteTodo = (index: number) => {
     setTodo((prev) => prev.filter((_, i) => i !== index));
    };
    

  2. スプレッド構文

    • 配列やオブジェクトを展開してコピーを作成します。
    const obj1 = { a: 1, b: 2 };
    const obj2 = { ...obj1, c: 3 };
    
    • obj1の全てのプロパティをコピーし、さらにc: 3を追加した新しいオブジェクトobj2を作成します。

  3. 分割代入

    • オブジェクトや配列から特定のプロパティや要素を抽出して変数に代入します。
    const user = { name: 'John', age: 30 };
    const { name, age } = user;
    
    • userオブジェクトからnameageを取り出して、それぞれ変数nameageに代入します。

  4. アロー関数

    • 簡潔な関数定義の方法です。
    const add = (a, b) => a + b;
    
    • abを引数として受け取り、それらの和を返す関数addを定義します。

  5. テンプレートリテラル

    • 文字列を簡単に組み立てる方法です。
    const name = 'John';
    const greeting = `Hello, ${name}!`;
    
    • 文字列内に変数nameの値を埋め込んで、Hello, John!という文字列を作成します。

  6. オプショナルチェイニング

    • 存在しないプロパティにアクセスしてもエラーにならないようにする構文です。
    const user = { address: { city: 'Tokyo' } };
    const city = user?.address?.city;
    
    • userオブジェクトのaddressプロパティが存在する場合にcityにアクセスします。

  7. Null合体演算子

    • 左側の値がnullまたはundefinedの場合に右側の値を返します。
    const name = user.name ?? 'Guest';
    
    • user.namenullまたはundefinedの場合、'Guest'を返します。

  8. findメソッド

    • 配列内の条件に一致する最初の要素を返します。
    const users = [{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }];
    const user = users.find(user => user.id === 1);
    
    • users配列からidが1の最初のユーザーを見つけます。

  9. reduceメソッド

    • 配列を一つの値にまとめます。
    const numbers = [1, 2, 3, 4];
    const sum = numbers.reduce((total, number) => total + number, 0);
    
    • numbers配列の全ての要素を合計してsumを計算します。

  10. プロパティショートハンド

    • オブジェクトリテラルの簡潔な記述方法です。
    const name = 'Alice';
    const age = 30;
    
    const person = {
      name: name, // この左辺と右辺が同じ場合は省略可能
      age: age
    };
    
    console.log(person); // { name: 'Alice', age: 30 }
    
    // 省略した形
    const name = 'Alice';
    const age = 30;
    
    const person = {
      name,
      age
    };
    
    console.log(person); // { name: 'Alice', age: 30 }
    
    
    • nameageをそのままオブジェクトのプロパティとして使用します。

  11. 論理AND (&&) 演算子

    • 条件が真の場合にのみ要素を表示します。
    const isLoggedIn = true;
    return (
      <div>
        {isLoggedIn && <button>Logout</button>}
      </div>
    );
    
    • isLoggedIntrueの場合にのみ<button>Logout</button>を表示します。

  12. 条件付きレンダリング(三項演算子)

    • 条件によって表示内容を切り替えます。
    const isLoggedIn = true;
    return (
      <div>
        {isLoggedIn ? <button>Logout</button> : <button>Login</button>}
      </div>
    );
    
    • isLoggedIntrueの場合は<button>Logout</button>を表示し、falseの場合は<button>Login</button>を表示します。

また、以下のように動的にスタイリングするためにもよく使用されます。

ボタンの有効/無効状態のスタイリング

import { useState } from 'react';
import { Button } from '@chakra-ui/react';

const DynamicButton = () => {
  const [isDisabled, setIsDisabled] = useState(true);

  return (
    <Button
      onClick={() => setIsDisabled(!isDisabled)}
      bg={isDisabled ? 'gray.400' : 'blue.500'}
      color={isDisabled ? 'white' : 'black'}
      cursor={isDisabled ? 'not-allowed' : 'pointer'}
      disabled={isDisabled}
    >
      {isDisabled ? 'Disabled' : 'Enabled'}
    </Button>
  );
};

export default DynamicButton;

アラートメッセージの種類に基づくスタイリング

import { Box } from '@chakra-ui/react';

const AlertMessage = ({ type, message }) => {
  return (
    <Box
      p={4}
      bg={
        type === 'success'
          ? 'green.200'
          : type === 'error'
          ? 'red.200'
          : 'gray.200'
      }
      color={
        type === 'success'
          ? 'green.800'
          : type === 'error'
          ? 'red.800'
          : 'gray.800'
      }
    >
      {message}
    </Box>
  );
};

export default AlertMessage;

  • 条件Aならこのスタイルをあてる、そうでなければBのスタイルをあてるといった具合です。

破壊的メソッドと非破壊的メソッドを理解する

JavaScriptにおけるよく使用されるメソッドを、破壊的メソッドと非破壊的メソッドに分類します。
なあなあにしがちですが、意外と重要な部分なので簡単に記載しておきます。

破壊的メソッド (Destructive Methods)

破壊的メソッドは、元の配列やオブジェクトを直接変更するメソッドです。

配列の破壊的メソッド

  1. push(): 配列の末尾に1つ以上の要素を追加します。
  2. pop(): 配列の末尾の要素を削除します。
  3. shift(): 配列の先頭の要素を削除します。
  4. unshift(): 配列の先頭に1つ以上の要素を追加します。
  5. splice(): 配列の指定された部分に要素を追加、削除、または置換します。
  6. sort(): 配列をソートします。
  7. reverse(): 配列の要素を反転させます。
  8. fill(): 配列の要素を指定した値で埋めます。

オブジェクトの破壊的メソッド

  1. Object.assign(): オブジェクトのプロパティを別のオブジェクトにコピーするためのメソッドです。複数のソースオブジェクトからターゲットオブジェクトにプロパティをコピーすることができます。
    const target = { a: 1, b: 2 };
    const source = { b: 4, c: 5 };
    
    const returnedTarget = Object.assign(target, source);
    
    console.log(target); // { a: 1, b: 4, c: 5 }
    console.log(returnedTarget); // { a: 1, b: 4, c: 5 }
    
    

  2. Object.freeze(): オブジェクトを凍結し、そのプロパティを変更できないようにするためのメソッドです。凍結されたオブジェクトは、プロパティの追加、削除、変更ができなくなります。
    ※元オブジェクトの中身は変わりませんが、状態が変わってしまう(追加、削除などができなくなる)ので破壊的とみなされます。
    const obj = {
      prop: 42
    };
    
    Object.freeze(obj);
    
    obj.prop = 33; // この変更は無視されます
    obj.newProp = 'new'; // この追加も無視されます
    delete obj.prop; // この削除も無視されます
    
    console.log(obj.prop); // 42
    console.log(obj.newProp); // undefined
    

  3. Object.seal(): オブジェクトをシール(封印)し、既存のプロパティを変更可能に保ちながら、新しいプロパティの追加や既存プロパティの削除を禁止するメソッドです。これにより、オブジェクトの形状が固定され、追加や削除による変更が防止されますが、プロパティの値は変更できます。
    const obj = {
      prop: 42
    };
    
    Object.seal(obj);
    
    obj.prop = 33; // プロパティの値は変更可能
    obj.newProp = 'new'; // 新しいプロパティの追加は無視される
    delete obj.prop; // プロパティの削除は無視される
    
    console.log(obj.prop); // 33
    console.log(obj.newProp); // undefined
    
    

破壊的な演算子

  1. delete: オブジェクトからプロパティを削除します。

非破壊的メソッド (Non-Destructive Methods)

非破壊的メソッドは、元の配列やオブジェクトを変更せず、新しい配列やオブジェクトを返すメソッドです。

配列の非破壊的メソッド

  1. concat(): 2つ以上の配列を結合します。
  2. slice(): 配列の一部を新しい配列として抽出します。
  3. map(): 配列の各要素に対して関数を適用し、新しい配列を返します。
  4. filter(): 条件を満たす要素を含む新しい配列を返します。
  5. reduce(): 配列を1つの値にまとめます。
  6. reduceRight(): 配列を右から左に1つの値にまとめます。
  7. find(): 条件を満たす最初の要素を返します。
  8. findIndex(): 条件を満たす最初の要素のインデックスを返します。
  9. some(): 少なくとも1つの要素が条件を満たすかをチェックします。
  10. every(): 全ての要素が条件を満たすかをチェックします。
  11. includes(): 配列が特定の要素を含むかをチェックします。
  12. indexOf(): 配列内の特定の要素の最初のインデックスを返します。
  13. lastIndexOf(): 配列内の特定の要素の最後のインデックスを返します.
  14. join(): 配列の全要素を文字列として結合します.

オブジェクトの非破壊的メソッド

  1. Object.keys(): オブジェクトのキーの配列を返します。
  2. Object.values(): オブジェクトの値の配列を返します。
  3. Object.entries(): オブジェクトのキーと値のペアの配列を返します。

予習編(React専用のHooks)

ちなみによくHook(フック)という言葉が用いられるのですが、これは特定のイベントやライフサイクルのタイミングで追加の処理を挿入するための仕組みのことです。

React初学者の方はここからは「こんなものがあるんだなぁ」くらいでいいと思います。
解説を最低限にしてますので、余裕があれば各Hooksを調べてみましょう。

  1. useStateフック

    • コンポーネント内で状態を管理するためのフックです。
    const [count, setCount] = useState(0);
    
    • countという状態変数を宣言し、初期値を0に設定します。setCountcountを更新するための関数です。

  2. useEffectフック

    • 副作用(データのフェッチやDOMの操作など)を実行するためのフックです。
    useEffect(() => {
      // コンポーネントがマウントされた時の処理
      return () => {
        // クリーンアップ処理
      };
    }, []);
    
    • 第二引数を使用して(ここでは[]のこと)、コンポーネントが初めて表示された時や特定の値が変化した時に実行される処理を記述します。

  3. useRefフック

    • DOM要素や値を保持するためのフックです。
    const inputRef = useRef(null);
    useEffect(() => {
      inputRef.current.focus();
    }, []);
    
    • inputRefを使って入力フィールドを参照し、コンポーネントが表示された時にフォーカスを当てます。

例えば、textareaに対してuseRefを使用して、入力された値を取得したりできます。

const SimpleTodo: NextPage = () => {
    // 省略
    const textAreaRef = useRef<HTMLTextAreaElement>(null);
    
    return (
        <textarea
            ref={textAreaRef}
            placeholder="useRefを使用したTodoアプリ" />
     )
 }
// 取得方法
const textAreaValue = textAreaRef.current?.value;

4.useContextフック

  • Reactアプリケーション全体でデータをグローバルに共有するためフックです。
    const MyContext = CreateContext();
    const value = useContext(MyContext);
    
    • MyContextから値を取得します。

5.useMemoフック

  • レンダー間で計算結果をキャッシュ(メモ化)するためのフックです。
    const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
    
    • abが変わらない限り、computeExpensiveValueの結果を再計算せずに返します。

6.useCallbackフック

  • 関数をメモ化するためのフックです。
    const memoizedCallback = useCallback(() => {
      doSomething(a, b);
    }, [a, b]);
    
    • abが変わらない限り、同じ関数インスタンスを返します。

7.useState useEffect使用したfetch API

  • ネットワークリクエストを送信してデータを取得するためのAPIです。
    const DataFetchingComponent = () => {
    const [data, setData] = useState(null); // useState フックを使用して state を定義
    
    useEffect(() => {
        fetch('https://api.example.com/data')
          .then(response => response.json())
          .then(data => setData(data)); // 取得したデータを state にセット
      }, []); // 空の依存配列により、コンポーネントの初回マウント時のみ実行
      
      return (
              // 省略
          );
      }
    
    • APIからデータを取得してsetDataで状態を更新します。

注意点

useEffect, useMemo, useCallbackの第2引数が変化しない=実行されない」ではないのでご注意ください。

例えばコンポーネントの状態が変わったり、親コンポーネントが再レンダリングされたりすると、Reactのスケジューリングの関係で依存配列が変わっていなくても再実行される場合があります。他にも要因はありますが頭の片隅に入れておきましょう。

おススメの書籍

最近はリスキリングサービスの発展で動画学習が主体になっていますが、手元に一冊あると重宝する位置づけのものを紹介します。

独習JavaScript
https://amzn.to/3KkBWEG

この書籍のいいところは、「初心者はスキップしていいところ」「レベルアップしたい人用」 などが項目に記載してあって、さらにJSのメカニズム的な部分から丁寧に説明されてあるので、辞書的な使い方でもいいですし、ゆっくりわからないところはGPTに聞きながら独習するという感じでもかなり勉強になります。

【補足】たまに使うメソッドを紹介する(初心者スルーしてOK)

flatMap()

flatMap()は配列内の各要素に対して指定された関数を適用し、その結果をフラットな配列として結合します。これはmap()flat()を一度に行うような動作をします。

基本的な使い方

const array = [1, 2, 3, 4];
const result = array.flatMap(x => [x, x * 2]);
console.log(result); // [1, 2, 2, 4, 3, 6, 4, 8]

この例では、元の配列の各要素に対して、要素自身とその2倍の値を持つ配列を返し、その結果をフラットな配列として結合しています。

使い方の例

  1. ネストされた配列のフラット化:
    flatMap()は、ネストされた配列を1段階フラットにするのに便利です。

    const nestedArray = [[1], [2], [3], [4]];
    const flatArray = nestedArray.flatMap(x => x);
    console.log(flatArray); // [1, 2, 3, 4]
    

  2. フィルタリングとマッピングの組み合わせ:
    flatMap()を使うと、フィルタリングとマッピングを一度に行うことができます。

    const numbers = [1, 2, 3, 4, 5];
    const evenSquares = numbers.flatMap(x => x % 2 === 0 ? [x * x] : []);
    console.log(evenSquares); // [4, 16]
    

    この例では、偶数の要素だけを2乗して返し、フラットな配列にしています。

  3. 複雑な変換:
    flatMap()を使って、各要素をより複雑な構造に変換することもできます。

    const sentences = ["this is a sentence", "another sentence"];
    const words = sentences.flatMap(sentence => sentence.split(" "));
    console.log(words); // ["this", "is", "a", "sentence", "another", "sentence"]
    

    この例では、文を単語に分割し、すべての単語を一つのフラットな配列にしています。

参考資料


終わりに

全て覚える必要はありませんが、それぞれの特徴を理解してどういう動きをするかだけは押さえておきましょう。
特に破壊的メソッドと非破壊的メソッドに関しては、「元のオブジェクトそのものの状態や性質を変更してしまう」ものとそうでないものがあるという認識で頭に入れておけばいいと思います。

それぞれの理解ができたらGPT先生に聞いて、実際にそのメソッドや構文を利用した実用例を出してもらって理解を深めるとさらにいいと思います。

61
79
3

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
61
79