Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | 1x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x | import React, { useState, useRef, useEffect } from "react"; import { Switch } from "@tencent/tea-component/lib/switch"; import { Modal } from "@tencent/tea-component/lib/modal"; export default function SwitchAsyncExample() { return ( <> <p> <AsyncSwitch block={false} /> </p> <p> <AsyncSwitch block /> </p> </> ); } function AsyncSwitch({ block }) { const [checked, loading, change] = useAsyncCheck(block, 1000); const blockText = block ? "模拟操作失败" : "模拟操作成功"; return ( <Switch value={checked} loading={loading} disabled={loading} onChange={value => change(value)} > {loading ? "请稍候..." : blockText} </Switch> ); } // 这里用 React Hooks 实现,使用 class 的同学可以自行改造 /** * @param {boolean} block 是否模拟失败情形 * @param {number} timeout 模拟的异步时长 * @returns {[boolean, boolean, (checked: boolean) => {}]} */ function useAsyncCheck(block, timeout) { // 选中和 loading 态 const [checked, setChecked] = useState(false); const [loading, setLoading] = useState(false); // 当前执行中的任务 const taskRef = useRef(null); // 组件 unmount 的时候清理当前任务 useEffect( () => () => { Iif (taskRef && taskRef.current) { taskRef.current.cancel(); taskRef.current = null; } }, [] ); // 处理切换逻辑 const change = async newChecked => { // 先切目标状态,给用户操作反馈 setChecked(newChecked); setLoading(true); // 创建切换异步任务 const task = simulateAsyncTask(block, timeout); // 任务挂载起来,可以取消之 taskRef.current = task; // 执行异步任务 try { await task.run(); } catch (err) { // 失败了恢复到原来的勾选状态 setChecked(checked); Modal.error({ message: "切换失败", description: err.message }); } finally { // 无论成功失败,都退出 loading 态,并清理任务引用 taskRef.current = null; setLoading(false); } }; return [checked, loading, change]; } function simulateAsyncTask(block, timeout) { let timer; return { cancel: () => clearTimeout(timer), run: () => new Promise((resolve, reject) => { timer = setTimeout( () => (!block ? resolve() : reject(new Error("blocked!"))), timeout ); }), }; } |