React 19 use API与NextJS 15异步参数的测试方案咨询
测试Next.js 15中用React 19
use API处理Promise参数的客户端组件 背景
在Next.js 14里,我们测试带动态URL参数的客户端组件/页面时,写法如下:
type PageProps = { params: { date: string } } const SomePage: FC<PageProps> = ({ params }) => { const { date } = params; // ...组件逻辑 }
对应的测试代码:
it('renders expected week', () => { render(<SomePage params={{ date: '2024-03-20' }} />); expect(screen.getByText('THIS WEEK')).toBeInTheDocument(); });
升级到Next.js 15后,params变成了Promise类型,需要用React 19的use API解析:
type PageProps = { params: Promise<{ date: string }> } const SomePage: FC<PageProps> = ({ params }) => { const { date } = use(params); // ...组件逻辑 }
遇到的问题
我们尝试直接传入Promise.resolve({ date: '2024-03-20' })作为params,但测试中Promise始终无法resolve,断言失败:
it('renders expected week', async () => { render(<Page params={Promise.resolve({ date: '2024-03-20' })} />); expect(screen.getByText('THIS WEEK')).toBeInTheDocument(); });
而改用useEffect手动解析Promise的写法,测试能正常运行:
const SomePage: FC<PageProps> = ({ params }) => { const [date, setDate] = useState(""); useEffect(() => { params.then((resolvedParams) => { setDate(resolvedParams.date); }); }); // ...组件逻辑 }
最佳测试方案
要正确测试用use API处理Promise参数的组件,核心是等待React完成Promise解析和组件重渲染,以下是几种可行方式:
1. 用waitFor等待组件更新
React的use API会在Promise resolve后触发组件重渲染,同步断言会在更新前执行,因此需要用Testing Library的waitFor包裹断言,等待目标元素出现:
it('renders expected week', async () => { render(<SomePage params={Promise.resolve({ date: '2024-03-20' })} />); await waitFor(() => { expect(screen.getByText('THIS WEEK')).toBeInTheDocument(); }); });
2. 用Next.js官方测试工具的异步render
Next.js提供的next/testing包中的render是异步函数,能自动处理React 19的异步渲染逻辑,无需额外编写waitFor:
import { render } from 'next/testing'; it('renders expected week', async () => { await render(<SomePage params={Promise.resolve({ date: '2024-03-20' })} />); expect(screen.getByText('THIS WEEK')).toBeInTheDocument(); });
3. 提前让Promise进入resolved状态(可选)
如果想确保Promise在渲染前就已resolve,可以先await目标Promise,再传入组件:
it('renders expected week', async () => { const mockParams = Promise.resolve({ date: '2024-03-20' }); await mockParams; // 让Promise提前进入resolved状态 render(<SomePage params={mockParams} />); await waitFor(() => { expect(screen.getByText('THIS WEEK')).toBeInTheDocument(); }); });
失败原因说明
React 19的use API处理Promise时会触发异步渲染更新,你之前的测试是同步执行断言,此时Promise尚未resolve、组件未完成更新,自然找不到目标元素。使用waitFor或异步render就能等待组件更新完成后再执行断言。
内容的提问来源于stack exchange,提问作者James Crowley
相关产品推荐
相关产品推荐

