web-dev-qa-db-ja.com

useEffect()フック内で呼び出される関数はどこに宣言すればよいですか?

状態に依存する関数を呼び出すuseEffectを使用すると、次のような状況になります。

例:

_// INSIDE APP COMPONENT

const [someState, setSomeState] = React.useState(0);
const [someTrigger, setSomeTrigger] = React.useState(false);

function someFunction() {
  return someState + 1;  
}

React.useEffect(() => {

  const newState = someFunction();  // 'someFunction' IS BEING CALLED HERE
  setSomeState(newState);

},[someTrigger])
_

質問:

この場合、someFunctionuseEffect()の内部で宣言する必要がありますか、それとも外部(コンポーネントの本体の内部)に保持しても安全ですか?

dependency配列に追加することもできますが、triggerに焦点を当てたいので、コードの再利用性を損なうことになります。

useEffect()は新しいレンダーの後に実行されるため、内部に呼び出す関数の新しいコピーがあると想定しても安全ですか?

useEffectフック内で関数を宣言する必要がある場合、または依存関係配列に関数を追加する必要がある場合の基本的なルールはありますか?

EDIT:これらの関数は最新のuseEffect変数にアクセスする必要があるため、stateにはこれらの関数の新しいコピーが必要です。

注:

このコードは、CodeSandboxで次のeslint警告をトリガーします。正常に動作しますが。

ReactフックReact.useEffectには依存関係がありません: 'someFunction'。含めるか、依存関係配列を削除してください。 (react-hooks/exhaustive-deps)eslint

実際のケースのシナリオ:

これは簡単な例です。私の実際の場合、これはフィルターコンポーネントを備えた製品検索ページです。したがって、フィルターをクリックしてアクティブ化(たとえば、_price <= 50_)すると、activePriceFilters状態変数を「リッスン」しているuseEffect()がトリガーされます。次に、その効果はsomeFunctionを計算し、新しいfilteredList状態に新しいproductListを設定する関数(例ではfilteredList)を呼び出します。

[〜#〜]スニペット[〜#〜]

_function App() {
  
  const [someState, setSomeState] = React.useState(0);
  const [someTrigger, setSomeTrigger] = React.useState(false);
  
  function someFunction() {
    return someState + 1;  
  }
  
  React.useEffect(() => {
  
    const newState = someFunction();
    setSomeState(newState);
  
  },[someTrigger])
  
  return(
    <React.Fragment>
      <div>I am App</div>
      <div>My state: {someState}</div>
      <button onClick={()=>setSomeTrigger((prevState) => !prevState)}>Click</button>
    </React.Fragment>
  );
}

ReactDOM.render(<App/>, document.getElementById('root'));_
_<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>_
5
cbdeveloper

別の状態を設定しても、まったく効果がありません。

 const [someState, setSomeState] = React.useState(0);

 function increaseState() {
    setSomeState(someState + 1);
 }
1
Jonas Wilms