何があった?
react-hooks-testing-libraryを使ってcustom hooksをテストした際にhooks内で作ったstateが更新されない問題が起きたのでその対処法を書き残します。
※↓はサンプルコード
import { useCallback, useState } from "react"
const useCount = () => {
const [count, setCount] = useState<number>(0)
const increment = useCallback(() => setCount((x) => x + 1), [])
return {
count: count,
increment: increment
}
}
export default useCount
import { renderHook } from "@testing-library/react"
import { act } from "react-dom/test-utils"
import useCount from "./count"
test("should count up", () => {
const { result } = renderHook(() => useCount())
const { count, increment } = result.current
act(() => {
increment()
increment()
increment()
})
expect(count).toBe(3) \\ count = 0になる
})
解決策
当たり前のような話ですが、result.currentは現在の値しか保持してくれないらしいです。なので一回取り出すとsetStateで更新しても反映されません。ということで正しいコードは↓のようになるらしいです。
import { renderHook } from "@testing-library/react"
import { act } from "react-dom/test-utils"
import useCount from "./count"
test("should count up", () => {
const { result } = renderHook(() => useCount())
const { increment } = result.current
act(() => {
increment()
increment()
increment()
})
expect(result.current.count).toBe(3) \\ 現在の値を取り出したいなら毎回result.currentから取り出す
})
まとめ
今回の敗因はreactのライフサイクルをきちんと把握していないせいだと思います。これに関しても一度勉強し直してまとめたほうがよいかしら...