Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

©2018 Wantedly, Inc. Agenda - Hooks Λద੾ʹϝϞԽ͢Δ - react-hooks/exhaustive-deps Λઃఆ͢Δ - stop-runaway-react-effects ͰϧʔϓΛ؂ࢹ͢Δ

Slide 5

Slide 5 text

©2018 Wantedly, Inc. HooksΛద੾ʹϝϞԽ͢Δ

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

©2018 Wantedly, Inc. e.g. useRect: divͷେ͖͞Λऔಘ͢ΔCustom Hooks export const useRect = () => { const [rect, setRect] = useState(); const ref = useRef(null); const resize = useCallback(() => { const target = ref.current; if (target) { const rect = target.getBoundingClientRect(); setRect(rect); } }, []); useEffect(() => resize(), [resize]); return { ref, rect }; } useCallbackͰؔ਺ΛϝϞԽ͢Δ

Slide 9

Slide 9 text

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

count: {count}

); };

Slide 10

Slide 10 text

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

count: {count}

); }; count ͷࢀর͕ݹ͍

Slide 11

Slide 11 text

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

count: {count}

); }; count ΛୈೋҾ਺ʹ௥Ճ͢Δ

Slide 12

Slide 12 text

©2018 Wantedly, Inc. e.g. Hooks Λద੾ʹϝϞԽ͢Δ - useCallbackΛ࢖༻͠ඳը͝ͱͷؔ਺ͷੜ੒Λ๷͙ - useCallbackͷୈೋҾ਺Λద੾ʹઃఆ͢Δ - useMemo Ͱ΋ಉ༷ Ͳ͏΍ͬͯ֬ೝ͢Δʁ

Slide 13

Slide 13 text

©2018 Wantedly, Inc. react-hooks/exhaustive-deps

Slide 14

Slide 14 text

©2018 Wantedly, Inc. react-hooks/exhaustive-deps ઃఆͯ͠·͔͢ʁ - eslintͷreact-hooksͷrule - ඳը͝ͱʹؔ਺͕มߋ͞ΕΔ৔߹ - Hooks಺Ͱࢀর͞ΕΔม਺ΛୈೋҾ਺ʹઃఆ͍ͯ͠ͳ͍৔߹

Slide 15

Slide 15 text

©2018 Wantedly, Inc. react-hooks/exhaustive-deps ઃఆͯ͠·͔͢ʁ ReactͷެࣜυΩϡϝϯτͰ΋ઃఆ͢Δ͜ͱΛ͓קΊ͍ͯ͠Δ IUUQTSFBDUKTPSHEPDTIPPLTSFGFSFODFIUNMVTFF⒎FDU

Slide 16

Slide 16 text

©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 }, []);

Slide 17

Slide 17 text

©2018 Wantedly, Inc. stop-runaway-react-effects

Slide 18

Slide 18 text

©2018 Wantedly, Inc. exhaustive-deps Ͱ͸νΣοΫͰ͖ͳ͍έʔε const handleResize = debounce(resize, 16); useEffect(() => { handleResize(); window.addEventListener("resize", handleResize); return () => { window.removeEventListener("resize", handleResize); }; }, [handleResize]); →ؒ઀తʹؔ਺͕มԽ͢Δ৔߹

Slide 19

Slide 19 text

©2018 Wantedly, Inc. stop-runaway-react-effects

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

©2018 Wantedly, Inc. ·ͱΊ - ద੾ʹϝϞԽΛߦ͍ແݶϧʔϓΛආ͚Δ - react-hooks/exhaustive-deps Λઃఆ͢Δ - stop-runaway-react-effects ͰϧʔϓΛ؂ࢹ͢Δ