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

React Hooks を安全に使う

React Hooks を安全に使う

Eef36ddd9ee17bc2077ac2cf754e84e1?s=128

kobayang

May 27, 2019
Tweet

Transcript

  1. ©2018 Wantedly, Inc. React HooksΛ҆શʹ࢖͏ React.js meetup #7 25.Jan.2019 -

    Naoki Kobayashi
  2. ©2018 Wantedly, Inc. Naoki Kobayashi GitHub: @kobayang Twitter: @kbys_02 I’m

    an Engineer @Wantedly
  3. ©2018 Wantedly, Inc. ͜Μͳܦݧ͋Γ·ͤΜ͔ʁ

  4. ©2018 Wantedly, Inc. Agenda - Hooks Λద੾ʹϝϞԽ͢Δ - react-hooks/exhaustive-deps Λઃఆ͢Δ

    - stop-runaway-react-effects ͰϧʔϓΛ؂ࢹ͢Δ
  5. ©2018 Wantedly, Inc. HooksΛద੾ʹϝϞԽ͢Δ

  6. ©2018 Wantedly, Inc. e.g. useRect: divͷେ͖͞Λऔಘ͢ΔCustom Hooks export const useRect

    = () => { const [rect, setRect] = useState<ClientRect | DOMRect>(); const ref = useRef<HTMLDivElement | null>(null); const resize = () => { const target = ref.current; if (target) { const rect = target.getBoundingClientRect(); setRect(rect); } }; useEffect(() => resize(), [resize]); return { ref, rect }; }
  7. ©2018 Wantedly, Inc. e.g. useRect: divͷେ͖͞Λऔಘ͢ΔCustom Hooks export const useRect

    = () => { const [rect, setRect] = useState<ClientRect | DOMRect>(); const ref = useRef<HTMLDivElement | null>(null); const resize = () => { const target = ref.current; if (target) { const rect = target.getBoundingClientRect(); setRect(rect); } }; useEffect(() => resize(), [resize]); return { ref, rect }; } resizeؔ਺͸ඳը͝ͱʹੜ੒͞Εͯ͠·͏
  8. ©2018 Wantedly, Inc. e.g. useRect: divͷେ͖͞Λऔಘ͢ΔCustom Hooks export const useRect

    = () => { const [rect, setRect] = useState<ClientRect | DOMRect>(); const ref = useRef<HTMLDivElement | null>(null); const resize = useCallback(() => { const target = ref.current; if (target) { const rect = target.getBoundingClientRect(); setRect(rect); } }, []); useEffect(() => resize(), [resize]); return { ref, rect }; } useCallbackͰؔ਺ΛϝϞԽ͢Δ
  9. ©2018 Wantedly, Inc. e.g. counter const App: React.FC = ()

    => { const [count, setCount] = useState(0); const addCount = useCallback(() => { setCount(count + 1); }, []); return ( <div> <button onClick={() => addCount()}>Add Count</button> <p>count: {count}</p> </div> ); };
  10. ©2018 Wantedly, Inc. e.g. counter const App: React.FC = ()

    => { const [count, setCount] = useState(0); const addCount = useCallback(() => { setCount(count + 1); }, []); return ( <div> <button onClick={() => addCount()}>Add Count</button> <p>count: {count}</p> </div> ); }; count ͷࢀর͕ݹ͍
  11. ©2018 Wantedly, Inc. e.g. counter const App: React.FC = ()

    => { const [count, setCount] = useState(0); const addCount = useCallback(() => { setCount(count + 1); }, [count]); return ( <div> <button onClick={() => addCount()}>Add Count</button> <p>count: {count}</p> </div> ); }; count ΛୈೋҾ਺ʹ௥Ճ͢Δ
  12. ©2018 Wantedly, Inc. e.g. Hooks Λద੾ʹϝϞԽ͢Δ - useCallbackΛ࢖༻͠ඳը͝ͱͷؔ਺ͷੜ੒Λ๷͙ - useCallbackͷୈೋҾ਺Λద੾ʹઃఆ͢Δ

    - useMemo Ͱ΋ಉ༷ Ͳ͏΍ͬͯ֬ೝ͢Δʁ
  13. ©2018 Wantedly, Inc. react-hooks/exhaustive-deps

  14. ©2018 Wantedly, Inc. react-hooks/exhaustive-deps ઃఆͯ͠·͔͢ʁ - eslintͷreact-hooksͷrule - ඳը͝ͱʹؔ਺͕มߋ͞ΕΔ৔߹ -

    Hooks಺Ͱࢀর͞ΕΔม਺ΛୈೋҾ਺ʹઃఆ͍ͯ͠ͳ͍৔߹
  15. ©2018 Wantedly, Inc. react-hooks/exhaustive-deps ઃఆͯ͠·͔͢ʁ ReactͷެࣜυΩϡϝϯτͰ΋ઃఆ͢Δ͜ͱΛ͓קΊ͍ͯ͠Δ IUUQTSFBDUKTPSHEPDTIPPLTSFGFSFODFIUNMVTFF⒎FDU

  16. ©2018 Wantedly, Inc. disableʹ͢Δ৔߹͸ඞͣཧ༝Λॻ͘ useEffect(() => { // apolloClient ͸ඳը͝ͱʹੜ੒͞ΕͯΔͨΊઃఆ͠ͳ͍

    // eslint-disable-next-line react-hooks/exhaustive-deps }, [paramId]); useEffect(() => { // mount࣌ʹҰ౓͚࣮ͩߦ͍ͨ͠ͷͰ deps Λۭʹ͍ͯ͠·͢ɻ // eslint-disable-next-line react-hooks/exhaustive-deps }, []);
  17. ©2018 Wantedly, Inc. stop-runaway-react-effects

  18. ©2018 Wantedly, Inc. exhaustive-deps Ͱ͸νΣοΫͰ͖ͳ͍έʔε const handleResize = debounce(resize, 16);

    useEffect(() => { handleResize(); window.addEventListener("resize", handleResize); return () => { window.removeEventListener("resize", handleResize); }; }, [handleResize]); →ؒ઀తʹؔ਺͕มԽ͢Δ৔߹
  19. ©2018 Wantedly, Inc. stop-runaway-react-effects

  20. ©2018 Wantedly, Inc. stop-runaway-react-effects - Ͳͷ effect callback Ͱ
 ϧʔϓ͕ى͖͍ͯΔ͔

    - ͲͷҾ਺͕มԽ͍ͯ͠Δ͔
  21. ©2018 Wantedly, Inc. ·ͱΊ - ద੾ʹϝϞԽΛߦ͍ແݶϧʔϓΛආ͚Δ - react-hooks/exhaustive-deps Λઃఆ͢Δ -

    stop-runaway-react-effects ͰϧʔϓΛ؂ࢹ͢Δ