Upgrade to Pro — share decks privately, control downloads, hide ads and more …

React Hooks勉強会 vol.5

React Hooks勉強会 vol.5

社内勉強会の資料です。
https://water-cell.connpass.com/event/178647/

yukikayuki

June 18, 2020
Tweet

More Decks by yukikayuki

Other Decks in Programming

Transcript

  1. ࣗݾ঺հ • State • Kaneda Takayuki • Web Application Developer

    • झຯ • Splatoon2, ᲔΛ৯΂Δ @_yukikayuki
  2. ✌ ϑοΫͷϧʔϧ • ϑοΫ͸ؔ਺ͷτοϓϨϕϧͷΈͰݺͼग़ͯ͠ ͍ͩ͘͞ɻϧʔϓ΍৚݅෼ذ΍ωετͨؔ͠਺ ͷதͰϑοΫΛݺͼग़͞ͳ͍Ͱ͍ͩ͘͞ɻ • ϑοΫ͸ React ͷؔ਺ίϯϙʔωϯτͷ಺෦ͷ

    ΈͰݺͼग़͍ͯͩ͘͠͞ɻ௨ৗͷ JavaScript ؔ ਺಺Ͱ͸ݺͼग़͞ͳ͍Ͱ͍ͩ͘͞ɻ https://ja.reactjs.org/docs/hooks-overview.html#rules-of-hooks
  3. useCounter.js import {useState, useCallback} from 'react' export default function useCounter(initialValue

    = 0) { const [count, setCount] = useState(initialValue) const increment = useCallback(() => setCount((x) => x + 1), []) const reset = useCallback(() => setCount(initialValue), [initialValue]) return {count, increment, reset} }
  4. jest useContainer.test.js Error: Invalid hook call. Hooks can only be

    called inside of the body of a function component. This could happen for one of the following reasons: 1. You might have mismatching versions of React and the renderer (such as React DOM) 2. You might be breaking the Rules of Hooks 3. You might have more than one copy of React in the same app See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.
  5. ؀ڥߏங • yarn create react-app my-app • cd my-app •

    yarn add -D @testing-library/react-hooks react-testing-renderer
  6. useCounter.js import {useState, useCallback} from 'react' export default function useCounter(initialValue

    = 0) { const [count, setCount] = useState(initialValue) const increment = useCallback(() => setCount((x) => x + 1), []) const reset = useCallback(() => setCount(initialValue), [initialValue]) return {count, increment, reset} }
  7. Rendering import {renderHook} from "@testing-library/react-hooks"; import useCounter from "./useCounter"; test('should

    use counter', () => { const {result} = renderHook(() => useCounter()) expect(result.current.count).toBe(0) expect(typeof result.current.increment).toBe('function') expect(typeof result.current.reset).toBe('function') })
  8. Updates import {act, renderHook} from "@testing-library/react-hooks"; import useCounter from "./useCounter";

    test('should increment counter', () => { const {result} = renderHook(() => useCounter()) act(() => { result.current.increment() }) expect(result.current.count).toBe(1) })
  9. jest noAct.test.js import {renderHook} from "@testing-library/react-hooks"; import useCounter from "./useCounter";

    test('should increment counter', () => { const {result} = renderHook(() => useCounter()) result.current.increment() expect(result.current.count).toBe(1) })
  10. act()ແ͠ͷWarning Warning: An update to TestHook inside a test was

    not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://fb.me/react-wrap-tests-with-act in TestHook in Suspense
  11. Providing Props 1 import {act, renderHook} from "@testing-library/react-hooks"; import useCounter

    from "./useCounter"; test('should increment counter from custom initial value', () => { const {result} = renderHook(() => useCounter(9000)) act(() => { result.current.increment() }) expect(result.current.count).toBe(9001) })
  12. Providing Props 2 import {act, renderHook} from "@testing-library/react-hooks"; import useCounter

    from "./useCounter"; test('should reset counter to updated initial value 1', () => { let initialValue = 0 const {result, rerender} = renderHook(() => useCounter(initialValue)) initialValue = 10 rerender() act(() => { result.current.reset() }) expect(result.current.count).toBe(10) })
  13. Providing Props 3 import {act, renderHook} from "@testing-library/react-hooks"; import useCounter

    from "./useCounter"; test('should reset counter to updated initial value 2', () => { const {result, rerender} = renderHook(({initialValue}) => useCounter(initialValue), { initialProps: {initialValue: 0}, }) rerender({initialValue: 10}) act(() => { result.current.reset() }) expect(result.current.count).toBe(10) })
  14. react-hooks-testing-libraryʹ ॏཁͳ͜ͱ͕ॻ͔Ε͍ͯΔ NOTE it is not recommended to test single-use

    custom hooks in isolation from the components where it's being used. It's better to test the component that's using the hook rather than the hook itself. The React Hooks Testing Library is intended to be used for reusable hooks/libraries. ஫ɿ࢖͍ࣺͯͷΧελϜϑοΫΛɺͦΕ͕࢖༻͞Ε͍ͯΔίϯϙʔ ωϯτ͔Β੾Γ཭ͯ͠ςετ͢Δ͜ͱ͸͓קΊ͠·ͤΜɻϑοΫࣗ ମͰ͸ͳ͘ɺϑοΫΛ࢖༻͍ͯ͠ΔίϯϙʔωϯτΛςετ͢Δ͜ ͱΛ͓קΊ͠·͢ɻReact Hooks Testing Library ࠶ར༻Մೳͳϑο Ϋ/ϥΠϒϥϦͷͨΊʹ࢖༻͞ΕΔ͜ͱΛҙਤ͍ͯ͠·͢ɻ https://github.com/testing-library/react-testing-library#hooks
  15. ࣍ͷֶशύε • react-hooks-testing-libraryͷAdvanced HooksΛ΍ͬͯΈΔ • YoutubeͰ’ How To Test Custom

    Effect Hook - Custom Hooks Mini Course Part 5’ΛݟΔ • react-useͷςετίʔυΛ؍࡯͢Δ