状態に依存する関数を呼び出す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])
_
質問:
この場合、someFunction
をuseEffect()
の内部で宣言する必要がありますか、それとも外部(コンポーネントの本体の内部)に保持しても安全ですか?
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"/>
_
別の状態を設定しても、まったく効果がありません。
const [someState, setSomeState] = React.useState(0);
function increaseState() {
setSomeState(someState + 1);
}