(b) 使用-可减缓效应
运行可中止效果的超级简单反应钩子 AbortController API (英语).
检查现场DEMO。 。 。 .
有兴趣做这样的项目吗? 关闭 正在寻找 伟大的工程师 加入我们的队伍!
安装
yarn add @closeio/use-abortable-effect
福利
- 极轻重量(小于500B minzipped).
- 它使用
AbortControllerAPI 和它兼容fetchAPI (英语). - 如果浏览器不支持
AbortControllerAPI 然后钩子就跟普通的一样useEffect钩. 见 我能用吗 用于浏览器支持概览. - 没有其他第三方依赖关系.
API 差异关系 useEffect
- API 兼容
useEffect, (中文(简体) ), 其中,您通过输入时接受效果AbortSignal和你一样 能够返回一个接受AbortController举个例子. - 支持可中止
fetch请求. - 支持运行可以轻易中止的自定义操作/计算.
- 自动损坏对重运行( 或组件卸载) 的影响, 除非您提供 自定义清理函数.
useEffect(() => {
// do something
return () => {
/* cleanup */
};
}, [deps]);
const abortControllerRef = useAbortableEffect(
(abortSignal) => {
// do something
return (abortController) => {
/* do cleanup, you should probably abort */
};
},
[deps],
);
使用量
可中止 fetch 请求
import React from 'react';
import useAbortableEffect from '@closeio/use-abortable-effect';
export default function MyAbortableFetchComponent() {
const abortControllerRef = useAbortableEffect((abortSignal) =>
fetch(url, { signal: abortSignal })
.then(/* … */)
.catch((rejection) => {
if (rejection.name !== 'AbortError') {
// Re-throw or handle non-abort rejection in another way.
return Promise.reject(rejection);
}
}),
);
const handleManualAbort = () => abortControllerRef.current.abort();
// …
}
可中止的任意计算
import React from 'react';
import useAbortableEffect from '@closeio/use-abortable-effect';
export default function MyAbortableComputationComponent() {
const abortControllerRef = useAbortableEffect(abortSignal => {
new Promise((resolve, reject) => {
// Should be a DOMException per spec.
const abortRejection = new DOMException(
'Calculation aborted by the user',
'AbortError',
);
// Handle when abort was requested before starting the computation.
if (abortSignal.aborted) {
return reject(abortRejection);
}
// This simulates an expensive computation.
const timeout = setTimeout(() => resolve(1), 5000);
// Listen for abort request.
abortSignal.addEventListener('abort', () => {
clearTimeout(timeout);
reject(abortRejection);
});
})
.then(/* … */)
.catch(rejection => {
if (rejection.name !== 'AbortError') {
// Re-throw or handle non-abort rejection in another way.
return Promise.reject(rejection);
}
}),
});
const handleManualAbort = () => abortControllerRef.current.abort();
// …
}
自定义清理功能
import React from 'react';
import useAbortableEffect from '@closeio/use-abortable-effect';
export default function MyCustomCleanupComponent() {
const [gotAborted, setGotAborted] = useState(false);
const abortControllerRef = useAbortableEffect((abortSignal) => {
fetch(url, { signal: abortSignal })
.then(/* … */)
.catch((rejection) => {
if (rejection.name !== 'AbortError') {
// Re-throw or handle non-abort rejection in another way.
return Promise.reject(rejection);
}
});
// Just return a function like in `useEffect`, with the difference that you
// get the abort controller (not a ref) as a param.
return (controller) => {
controller.abort();
setGotAborted(true);
};
});
const handleManualAbort = () => abortControllerRef.current.abort();
// …
}
许可证
麻省理工学院 关闭