from 非同期なReactの状態更新をテストする
resolveをawaitしたらたまたま動いたけど不適切
resolveの前にawaitをつけたらテストがたまたま通ったが、よく考えるとresolveはPromiseを返さないのでこれをawaitするのは筋が通らない
TypeScriptも警告する: 'await' has no effect on the type of this expression. ts(80007)
なぜこの書き方で動いたのかはまだよくわかってないが、少なくともこの書き方は正しい書き方ではないので、本題のストーリーに混ぜると混乱するから切り出しておくことにした。
下記のように書き換えると1,2,3,4,5,6,1,2,7の順で実行されるようになる。
ts
export const MyAsyncComponent = () => {
const [value, setValue] = useState(0);
console.log(1);
userTrigger = () => {
console.log(4);
return new Promise<number>((res) => {
resolve = res;
}).then((x) => {
console.log(6);
setValue(x);
});
};
console.log(2);
return <span>{value}</span>;
};
ts
render(<MyAsyncComponent />);
expect(screen.getByText("0")).toBeTruthy();
console.log(3);
userTrigger();
console.log(5);
expect(screen.getByText("0")).toBeTruthy();
await resolve(1);
console.log(7);
expect(screen.queryByText("0")).toBeNull();
expect(screen.getByText("1")).toBeTruthy();
(追記: await resolve(1);はおかしい)
setValueでの更新をactで包むためにuseStateを差し替える
警告も消えてテストが通るようになった。めでたしめでたし。 full source code: https://gist.github.com/nishio/06249db25dafef81646d961ec9c0c70e