を使用して、対応するコンポーネント内の非同期コードの自動キャンセル
16134 ワード
私は、実験的な
:
useAsyncEffect
とuseAsyncCallback
(use-async-effect2 NPMパッケージ)を部品をアンマウントするとき、自動的に内部のasyncルーチンをキャンセルすることができるフックを作りました.また、ユーザによってキャンセル動作を高めることもできる.非同期ルーチンを正しくキャンセルすることは、周知の反応警告を避けるために重要です.Warning: Can't perform a React state update on an unmounted component. This is an no-op, but it indicates a memory leak in your application.
それを働かせるために、ジェネレータはasync機能の交換として使われて、基本的に、yield
の代わりにawait
キーワードを使用するだけです.キャンセル可能な約束は、もう一つの私のプロジェクト―CPromise(cpromise2)によって提供されます.useAsyncEffect
最小限の例(注意してください.import React, { useState } from "react";
import { useAsyncEffect } from "use-async-effect2";
import cpFetch from "cp-fetch"; //cancellable c-promise fetch wrapper
export default function TestComponent(props) {
const [text, setText] = useState("");
useAsyncEffect(
function* () {
setText("fetching...");
const response = yield cpFetch(props.url);
const json = yield response.json();
setText(`Success: ${JSON.stringify(json)}`);
},
[props.url]
);
return <div>{text}</div>;
}
エラー処理によるimport React, { useState } from "react";
import { useAsyncEffect, E_REASON_UNMOUNTED } from "use-async-effect2";
import { CanceledError } from "c-promise2";
import cpFetch from "cp-fetch";
export default function TestComponent(props) {
const [text, setText] = useState("");
const cancel = useAsyncEffect(
function* ({ onCancel }) {
console.log("mount");
this.timeout(5000);
onCancel(() => console.log("scope canceled"));
try {
setText("fetching...");
const response = yield cpFetch(props.url);
const json = yield response.json();
setText(`Success: ${JSON.stringify(json)}`);
} catch (err) {
CanceledError.rethrow(err, E_REASON_UNMOUNTED); //passthrough
setText(`Failed: ${err}`);
}
return () => {
console.log("unmount");
};
},
[props.url]
);
return (
<div className="component">
<div className="caption">useAsyncEffect demo:</div>
<div>{text}</div>
<button onClick={cancel}>Abort</button>
</div>
);
}
remount
デモimport React from "react";
import { useState } from "react";
import { useAsyncCallback } from "use-async-effect2";
import { CPromise } from "c-promise2";
export default function TestComponent() {
const [text, setText] = useState("");
const asyncRoutine = useAsyncCallback(function* (v) {
setText(`Stage1`);
yield CPromise.delay(1000);
setText(`Stage2`);
yield CPromise.delay(1000);
setText(`Stage3`);
yield CPromise.delay(1000);
setText(`Done`);
return v;
});
const onClick = () => {
asyncRoutine(123).then(
(value) => {
console.log(`Result: ${value}`);
},
(err) => console.warn(err)
);
};
return (
<div className="component">
<div className="caption">useAsyncCallback demo:</div>
<button onClick={onClick}>Run async job</button>
<div>{text}</div>
</div>
);
}
どんなフィードバックでも有り難いです😊Reference
この問題について(を使用して、対応するコンポーネント内の非同期コードの自動キャンセル), 我々は、より多くの情報をここで見つけました https://dev.to/digitalbrainjs/useasynceffect-useasynccallback-hooks-518fテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol