Skip to main content

class based React.js hooks

class based React.js hooks

REF: [1]

Reactで複雑な処理を加えたとき、useMemo, useCallbackだらけになったり、 useRef, xxxRef.currentだらけになり、読みにくいコードになることがあります。 クラスベースで、Ctrlクラスを作成し、hookから操作します。 例として、useDelay.tsを定義します。 このフックは、実行を少し遅らせることで、重い処理などが重複するのを防ぎます。

import React from 'react'

class Ctrl {
listener = () => {};
callback = () => {};
timeStamp = 1000;

apply(callback = () => {}, timeStamp = 1000) {
this.callback = callback;
this.timeStamp = timeStamp;
return this.delay.bind(this);
}

delay(...args) {
const timeout = window.setTimeout(this.callback, this.timeStamp, ...args);
this.listener();
this.listener = () => void window.clearTimeout(timeout);
}
}

export default function $(callback = () => {}, timeStamp = 1000) {
const [ctrl] = React.useState(() => new Ctrl());
React.useEffect(() => ctrl.listener, [ctrl]);
return ctrl.apply(callback, timeStamp);
}

applyはstateが変化するごとにが実行され、状態や返す関数を更新しています。 delayは実行毎にlistenerをリセットし、時間がたつとcallbackを実行します。 次のアプリでは、文字の打ち込みが終わった1秒ごとに、callbackが動作します。 codesandbox でも試すことができます。

import React from "react";
import ReactDOM from "react-dom";
import $ from './useDelay';

function App() {
const [state, set] = React.useState`⚡Lets write here⚡`;
return (
<>
{ state }
<input
onKeyDown={(e) => set`🐛Now writing🐛`}
onKeyUp={$((e) => set`✅Completed✅`, 1000)}
/>
</>
);
}

ReactDOM.render(<App />, document.getElementById`root`);