我的异步组件渲染了两次,即使使用 await 也不会等待第二次?



我想测试一个简单的应用程序,它从输入中获取代码,然后在文档中显示代码。

我的组件渲染两次:一次没有输入值(我将useState初始化为undefined(;另一个带有正确字符串。我希望我的测试等待第二次,然后代码出现。现在在第一次渲染时失败。

这是我的测试:

test("Keeps track of input value [async]", async () => {
const { getByText, queryByText, getByLabelText, debug } = render(<App />);
userEvent.type(getByLabelText("Code:"), "12345")
userEvent.click(getByText(/Change route/i));
expect(await queryByText(/The code you chose is: 12345/i)).toBeInTheDocument();
});

这是我的应用程序代码:

const App = () => {
const [route, setRoute] = useState("home")
const [code, setCode] = useState("");
return (
<Router
currentRoute={route}
render={(currentRoute: string) => (
<Fragment>
<Router.View route="home" currentRoute={currentRoute}>
This is the homepage.
<label htmlFor="code">Code:</label><input id="code" type="text" value={code} onChange={(e) => setCode(e.target.value)} />
<button onClick={() => {
setRoute('selection')
}}>Change route</button>
</Router.View>
<Router.View route="selection" currentRoute={currentRoute}>
<Selection code={code} />
</Router.View>
</Fragment>
)}
/>
);
};

选择代码(Promise.resolve到模拟异步(:

编辑:事实证明useEffect甚至没有在第一个渲染上调用

const Selection = (props) => {
const [code, setCode] = useState();
useEffect(() => {
Promise.resolve(props.code).then(res => setCode("12345"));
},[props.code])
return (<>This is the selection page. The code you chose is: {code}</>)
}

制作了一个代码沙盒,但由于无关原因而失败。如果我能让它工作,我会更新:https://codesandbox.io/s/lingering-thunder-z9oqq

这个测试解决了我的问题:

test("Keeps track of input value [async]", async () => {
render(<App />);
userEvent.type(screen.getByLabelText(/Code:/i), "12345")
userEvent.click(screen.getByText(/Change route/i));
expect(await screen.findByText(/12345/i)).toBeInTheDocument();
});

仔细研究,我得出的结论是,我应该把screen.findByText()await作为一个元素来出现。根据Kent C Dodds ,queryBy*应主要用于断言不安全性

最新更新