[解決済み] React Hookでスロットルやデバウンスを使用するには?
質問
私は
throttle
メソッドから
lodash
を機能的なコンポーネントで使用する場合などです。
const App = () => {
const [value, setValue] = useState(0)
useEffect(throttle(() => console.log(value), 1000), [value])
return (
<button onClick={() => setValue(value + 1)}>{value}</button>
)
}
の中のメソッドなので
useEffect
の中のメソッドはレンダリングごとに再宣言されるので、スロットリング効果は働きません。
どなたか簡単な解決策をお持ちではないでしょうか。
どのように解決するのですか?
ある程度時間が経つと、自分で
setTimeout/clearTimeout
(を使って自分で処理する方が、関数型ヘルパーを使うよりずっと簡単だと思います。後の方の処理は、それを
useCallback
に適用した直後に、依存関係の変更のために再作成される可能性があるけれども、実行中の遅延をリセットしたくないという追加の課題が発生します。
以下はオリジナルの回答です。
あなたは(そしておそらく必要な)かもしれません
useRef
を使用して、レンダリングの間に値を保存することができます。ちょうど、それが
タイマーのために提案された
というようなもの
const App = () => {
const [value, setValue] = useState(0)
const throttled = useRef(throttle((newValue) => console.log(newValue), 1000))
useEffect(() => throttled.current(value), [value])
return (
<button onClick={() => setValue(value + 1)}>{value}</button>
)
}
については
useCallback
:
としても使えるかもしれません。
const throttled = useCallback(throttle(newValue => console.log(newValue), 1000), []);
しかし、コールバックを一度作り直そうとすると
value
が変更されます。
const throttled = useCallback(throttle(() => console.log(value), 1000), [value]);
が実行を遅らせないことがわかるかもしれません。
value
が変更されると、コールバックは直ちに再作成され、実行されます。
ということで
useCallback
は、遅延実行の場合、大きな利点はありません。それはあなた次第です。
[UPD】当初は
const throttled = useRef(throttle(() => console.log(value), 1000))
useEffect(throttled.current, [value])
しかし、その方法では
throttled.current
は初期
value
(0)にバインドされています。そのため、次のレンダリングでも変更されることはありませんでした。
ですから、関数を
useRef
に押し込むときには注意が必要です。
関連
-
[解決済み】無効な設定オブジェクトです。APIスキーマと一致しない設定オブジェクトを使用してWebpackが初期化されました。
-
[解決済み] マテリアルUIセレクトフィールドのマルチセレクト
-
[解決済み] React - 予想外のトークン、予想外の;
-
[解決済み] React TypeScriptで作業しているときに、Jestが予期しないトークンに遭遇した
-
[解決済み] validateDOMNesting警告React
-
[解決済み] は、gatsby-imageで動作する良いreactのカルーセルコンポーネントはありますか?[って聞かれます。]
-
[解決済み] create-react-appビルドスクリプトを実行する際に、ビルド.env変数を設定するには?
-
[解決済み] React」は定義される前に使用されていた
-
[解決済み] Reactコンポーネントに条件付きで属性を追加するにはどうすればよいですか?
-
[解決済み] useEffect React Hook使用時の依存性欠如の警告を修正する方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] ReactJsのCreateClassは関数ではない
-
[解決済み] reactstrapのドロップダウンで選択されたアイテムを設定する方法は?
-
[解決済み] React TypeScriptで作業しているときに、Jestが予期しないトークンに遭遇した
-
[解決済み] react.jsで複数のモジュールをエクスポートする
-
[解決済み] ReactJs "インバリアント違反..." リアクトの古典的な問題
-
[解決済み] eslint: no-case-declaration - case ブロックで予期しない字句の宣言があった。
-
[解決済み] ReactコンポーネントのJest SnapshotテストにおけるSnapshotテストの仕組みとtoMatchSnapshot()関数は何をするのか?
-
[解決済み] Error: yarn start - エラー コマンド "start" が見つかりません。
-
[解決済み] componentDidUpdate'メソッドはいつ使用するのですか?
-
[解決済み】ReactのuseEffectフックを初期レンダリング時に実行しないようにする