1.捕获promise
deepseek:React 的 Suspense 通过一种特殊的机制来捕获 Promise,从而实现异步操作的声明式处理。
那么我想看看是怎么回事
import { Suspense } from "react";
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Hello, world!");
}, 2000);
});
const MyComponent =async () => {
await myPromise.then((result) => {
console.log(result);
});
return <div>Hello, world!</div>;
};
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<MyComponent />
</Suspense>
);
}
export default App;
实现了效果,页面先Loading...,再Hello, world!
但是有警告和报错
<MyComponent> is an async Client Component. Only Server Components can be async at the moment. This error is often caused by accidentally adding `'use client'` to a module that was originally written for the server.
App.tsx:21
A component was suspended by an uncached promise. Creating promises inside a Client Component or hook is not yet supported, except via a Suspense-compatible library or framework.
2.useEffect
我经常在useEffect里获取数据并赋值到状态
就想放useEffect里
const MyComponent = async () => {
const proFun = async () => {
await myPromise
.then((result) => {
console.log(result);
})
};
useEffect(() => {
proFun();
}, []);
return <div>Hello, world!</div>;
};
效果丢失
https:
官网说:Suspense does not detect when data is fetched inside an Effect or event handler
3.use
react19新增api
实现效果,无警告无报错
import { Suspense, use } from "react";
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Hello, world!");
}, 2000);
});
const MyComponent = () => {
const data: any = use(myPromise);
return <div>{data}</div>;
};
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<MyComponent />
</Suspense>
);
}
export default App;
use(promise) {
const hook = mountWorkInProgressHook();
if (promise.status === 'pending') {
throw promise;
}
return promise.result;
},
4.重复请求
例子
例1:
function MyComponent() {
const data = use(fetch('/api/data'));
return <div>{data}</div>;
}
例2:
const MyComponent = () => {
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Hello, world!");
}, 2000);
});
const data: any = use(myPromise);
return <div>{data}</div>;
};
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<MyComponent />
</Suspense>
);
}
例3:
function MyComponent() {
const data = use(axios.get('/api/data'));
return <div>{data}</div>;
}
测试axios
const MyComponent = () => {
const getCapFunc = async () => {
const res = await getCaptchaReq({ email: "8100580@qq.com", type: "register" });
console.log(res);
};
useEffect(() => {
getCapFunc();
}, []);
return <div>{data}</div>;
};
const MyComponent = () => {
const data: any = use(getCaptchaReq({ email: "8100580@qq.com", type: "register" }));
return <div>{data.data}</div>;
};
type MyComponentProps = {
promise: Promise<any>;
};
const MyComponent = ({ promise }: MyComponentProps) => {
const data: any = use(promise);
return <div>{JSON.stringify(data)}</div>;
};
function App() {
const captchaPromise = getCaptchaReq({
email: "8100580@qq.com",
type: "register",
});
return (
<Suspense fallback={<div>Loading...</div>}>
<MyComponent promise={captchaPromise} />
</Suspense>
);
}