LoginSignup
0
0

useState( (*) => * ) の注意点

Posted at

結論

React の useState フックを使用する際、関数を状態として保持したいケースでは注意が必要です。

どんなコードだとまずいか

直接関数を useState に渡すと、意図せぬ挙動になる場合があります。
具体的には、

  • useState で, 値ではなく関数を保持したいとき

です. 以下のようなコードは避けるべきです。

const [stateFunction, setStateFunction] = useState(myFunction);

このコードでは、myFunction は初期状態を計算するために一度だけ実行され、その戻り値が state の初期値となります。これは、myFunction を関数として state に保持したい場合には適していません。

どのように実装すべきか

関数を state として保持する正しい方法は、その関数を返す別の関数にラップして useState に渡すことです。

const [stateFunction, setStateFunction] = useState(() => myFunction);

この形式では、myFunction は state の値として保持され、実行されません。これにより、関数を状態として適切に管理できます。

理由

useState は、初期状態を計算するために関数を一度だけ実行します。そのため、関数を直接渡すと、その関数は初期状態を生成するために使用され、関数そのものが state に保持されるわけではありません。これは、関数を状態として使用したい場合には望ましくありません。

ラップされた関数を使用することで、React はそのラップされた関数を実行し、その戻り値(この場合は myFunction)を初期状態として使用します。これにより、関数そのものが状態として保持されます。

より具体的に

誤った実装例

import React, { useState } from 'react';

function MyComponent() {
  const myFunction = () => {
    console.log("Function called");
    return "Hello World";
  };

  // ❌: myFunction は関数としては渡されず, myFunction の実行結果が渡されることになる
  const [stateFunction, setStateFunction] = useState(myFunction);

  console.log(stateFunction);
  // Log: "Hello World"
  // functin の情報が表示されると思いきや, myFunctionの実行結果が表示される

  return (
    <div>
      {/* Rest of the component */}
    </div>
  );
}

正しい実装例

import React, { useState } from 'react';

function MyComponent() {
  const myFunction = () => {
    console.log("Function called");
    return "Hello World";
  };

  // ⭕️: myFunction を 返す関数を渡す
  const [stateFunction, setStateFunction] = useState(() => myFunction);

  console.log(stateFunction);
  // log: myFunction の関数としての情報が出力される

  return (
    <div>
      {/* Rest of the component */}
    </div>
  );
}

まとめ

React の useState フックを使用して関数を状態として扱う場合は、関数を直接渡すのではなく、それを返す別の関数にラップして渡す必要があります。この方法により、関数は状態として正しく保持され、意図したとおりに機能します。

0
0
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
0
0