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

React Hooks

React Hooks

React hooks introduction

Simon Pai

March 08, 2019
Tweet

More Decks by Simon Pai

Other Decks in Programming

Transcript

  1. ಩ JS 蕦褾玕ጱӣय़ز㱸 TRANSPILER UI LIBRARY BUILD TOOL - ES6

    - Babel - TypeScript - JSX - Webpack - Browserify - Gulp - React - Vue - Bootstrap - Material UI
  2. Q: REACT HOOKS 磪ग़碝牫 ▸ [2018/10/25] React Conf 2018 獍૲

    ▸ [2019/1/9] Alpha release ▸ [2019/2/6] Stable release
  3. Q: REACT HOOKS 磪ग़ᄤ牫 ▸ [2018/10/25] React Conf 2018 獍૲

    ▸ [2018/10/26] ᒫӞ㮆 custom hooks npm publish ▸ [2018/10/26] Evan You 咳蔭䋿涢௔ጱ Vue Hooks ▸ [2018/10/26] ᐒᗭڊ匍碍܈㮆 custom hooks project ▸ [2019/1/9] Alpha release ▸ [2019/2/6] Stable release ֦㮉ฎࣁ盪Ջ讕ࠩ
  4. REACT: CLASS COMPONENT class CounterButton extends React.Component { constructor() {

    this.state = {value: 0}; this.onClick = this.onClick.bind(this); } onClick() { this.setState(state => ({value: state.value + 1})); } render() { return ( <button onClick={this.onClick}>{this.state.value}</button> ); } }
  5. CLASS COMPONENT VS FUNCTION COMPONENT class component function component construction

    class function stateful yes no side effect (life cycle) yes no access context yes no
  6. CLASS COMPONENT VS FUNCTION COMPONENT class component function component function

    component w/ hooks construction class function function stateful yes no yes side effect (life cycle) yes no yes access context yes no yes
  7. HOOKS function CounterButton({initialValue}) { const [value, setValue] = useState(initialValue); const

    plus1 = () => setValue(v => v + 1); return ( <button onClick={plus1}>{value}</button> ); }
  8. HOOKS function CounterButton({initialValue}) { const [value, setValue] = useState(initialValue); const

    plus1 = () => setValue(v => v + 1); return ( <button onClick={plus1}>{value}</button> ); }
  9. HOOKS function CounterButton({initialValue}) { const [value, setValue] = useState(initialValue); const

    plus1 = () => setValue(v => v + 1); return ( <button onClick={plus1}>{value}</button> ); } initial value get initial value value setter Mounting Render
  10. HOOKS function CounterButton({initialValue}) { const [value, setValue] = useState(initialValue); const

    plus1 = () => setValue(v => v + 1); return ( <button onClick={plus1}>{value}</button> ); } get current value same value setter Updating Render
  11. HOOKS ֵአ憒㳷ҁӞ҂ ▸ ݝ胼ࣁ render function Ӿ޷ݞ hooks API ▸

    ֕ฎ hooks ࢧ㯽ጱ獢碍ݢ犥ࣁ犨֜碻狡޷ݞ ▸ React Ꭳ螇匍ࣁྋࣁ render ߺ㮆 component牧ಅ犥 hooks Ꭳ螇Ԇ薫ฎ抑 ▸ 螭Ꭳ螇匍ࣁฎ mount ౲ฎ update
  12. HOOKS ֵአ憒㳷ҁӞ҂ setTimeout(() => { const [value, setValue] = useState(0);

    }, 1000); const [value, setValue] = useState(0); setTimeout(() => { setValue(1); }, 1000);
  13. HOOKS function CounterButton() { // we can have multiple useState()

    const [firstName, setFirstName] = useState('Alice'); const [lastName, setLastName] = useState('Smith'); return ( <div> <span>{firstName}</span> <span>{lastName}</span> </div> ); }
  14. HOOKS function CounterButton() { // we can have multiple useState()

    const [firstName, setFirstName] = useState('Alice'); const [lastName, setLastName] = useState('Smith'); return ( <div> <span>{firstName}</span> <span>{lastName}</span> </div> ); }
  15. HOOKS ֵአ憒㳷ҁԫ҂ ▸ ݶӞ㮆 component instance ጱྯ稞 render牧hooks API ጱ

    ޷ݞ䌘虡膏殼ଧ஠殾ፘݶ ▸ custom hooks ጱ䋿֢愊犖஠殾螈౮蝡㮆礿կ ▸ hooks 胙盅ጱ data model 疰ฎӞ㮆 array牧render Ӿྯ稞 call index 疰 +1
  16. HOOKS ֵአ憒㳷ҁԫ҂ if (props.someBoolean) { let [value, setValue] = useState(0);

    } for (let item of props.items) { let [value, setValue] = useState(0); }
  17. Q: HOOKS 磪ߺ犚 API牫 ▸ च๜ ▸ useState ▸ useEffect

    ▸ useContext ▸ ṛ褩 ▸ useReducer 缛 ▸ ૡٍ ▸ useMemo/useCallback ▸ useRef ▸ useDebugValue ▸ ᐒᗭ獺֢ ▸ www.hooks.guide ▸ react-hooks ▸ React Spring ਥො෈կ
  18. USE STATE // class const value = this.state.value; this.setState({value: newValue});

    // function + hooks const [value, setValue] = useState(initialValue); // expensive initialization const [value, setValue] = useState(() => initialValue); // value setter can take an updater callback setValue(v => v + 1);
  19. USE EFFECT // class componentDidMount() { setup(); } componentDidUpdate() {

    teardown(); setup(); } componentWillUnmount() { teardown(); } // function + hooks useEffect(() => { setup(); // executed at following component mount or update return teardown; // saved and called before next setup or at unmount });
  20. useEffect(() => { setup(); // executed at next component mount

    or update return teardown; // saved and called at next update or unmount }); USE EFFECT Teardown
  21. useEffect(() => { setup(); // executed at next component mount

    or update return teardown; // saved and called at next update or unmount }); USE EFFECT Teardown Teardown
  22. useEffect(() => { setup(); // executed at next component mount

    or update return teardown; // saved and called at next update or unmount }); USE EFFECT Teardown
  23. USE EFFECT // skip effect by comparing some input values

    const [count, setCount] = useState(0); useEffect(() => { document.title = `You clicked ${count} times`; }, [count]); // if count value equals previous value, nothing is called at // component update and saved teardown function is kept
  24. USE CONTEXT const MyContext = React.createContext(); function A() { return

    ( <MyContext.Provider value={42}> (...a deep tree w/ <B />) </MyContext.Provider> ); } function B() { return ( <MyContext.Consumer> {value => <div>{value}</div>} </MyContext.Consumer> ); }
  25. USE CONTEXT const MyContext = React.createContext(); function A() { return

    ( <MyContext.Provider value={42}> (...a deep tree w/ <B />) </MyContext.Provider> ); } function B() { const value = useContext(NumberContext); return ( <div>{value}</div> ); } // context update triggers rerender
  26. USE REF // in class component const onButtonClick = ()

    => { this.inputEl.focus(); }; return ( <> <input ref={(el) => {this.inputEl = el;}} type="text" /> <button onClick={onButtonClick}>Focus the input</button> </> );
  27. USE REF // function component + hooks const inputRef =

    useRef(null); const onButtonClick = () => { // `current` points to the mounted text input element inputRef.current.focus(); }; return ( <> <input ref={inputRef} type="text" /> <button onClick={onButtonClick}>Focus the input</button> </> );
  28. USE REF ▸ ֦ݢ犥೭ useRef 㬵ल犨֜䩚ᥜ ▸ 犋Ӟਧᥝฎ element ▸

    ݢ犥አ㬵猂懿匍ࣁฎᒫ皃稞 render ▸ ݢ犥አ㬵猂ਂӤӞ㮆 state ౲ props ▸ 綍ᛗݢ犥አ㬵猂ਂ function ▸ ޾ useState ጱ犋ݶ讨物update ref 犋䨝蝨౮ rerender ▸ 疰ฎӞ㮆㻌奈ጱ variable
  29. USE MEMO / USE CALLBACK // cache tool, recompute only

    when a or b is changed // only keep track of one previous value (and inputs) const memoizedValue = useMemo(() => compute(a, b), [a, b]); // never updated const memoizedValue = useMemo(() => compute(x, y), []); // can memoize anything, including a component tree const child = useMemo(() => <Child a={a} />, [a]); // cache tool for inline function const memoizedCallback = useCallback(() => {...}, inputs); // means const memoizedCallback = useMemo(() => () => {...}, inputs);
  30. USE REDUCER // works 87% like a redux reducer const

    [state, dispatch] = useReducer(reducer, initialState); // with init function const [state, dispatch] = useReducer(reducer, initState, initFn); // initial state would be initFn(initState) // won’t trigger a rerender when reducer returns previous state, // compared by Object.js()
  31. CUSTOM HOOKS const [value, setValue] = useState(0); const plus1 =

    () => setValue(value + 1); return ( <button onClick={plus1}>{value}</button> );
  32. CUSTOM HOOKS // custom hook function useIncrement(initialValue) { const [value,

    setValue] = useState(initialValue); const plus1 = () => setValue(value + 1); return [value, plus1]; } // render const [value, plus1] = useIncrement(0); return ( <button onClick={plus1}>{value}</button> );
  33. CUSTOM HOOKS // custom hook function useIncrement(initialValue) { const [value,

    setValue] = useState(initialValue); const plus1 = () => setValue(value + 1); return [value, plus1]; } // render const [value, plus1] = useIncrement(0); return ( <button onClick={plus1}>{value}</button> ); inline function new instance every render
  34. CUSTOM HOOKS // custom hook function useIncrement(initialValue) { const [value,

    setValue] = useState(initialValue); const plus1 = useCallback(() => setValue(value + 1), [value]); return [value, plus1]; } // render const [value, plus1] = useIncrement(0); return ( <button onClick={plus1}>{value}</button> );
  35. CUSTOM HOOKS // custom hook function useIncrement(initialValue) { const [value,

    setValue] = useState(initialValue); const plus1 = useCallback(() => setValue(v => v + 1)); return [value, plus1]; } // render const [value, plus1] = useIncrement(0); return ( <button onClick={plus1}>{value}</button> );
  36. CUSTOM HOOKS function MyComponent() { const [value, setValue] = useState(0);

    // return value in previous render const previousValue = usePrevious(value); return <h1>Now: {value}, before: {previousValue}</h1>; }
  37. CUSTOM HOOKS function MyComponent() { const [value, setValue] = useState(0);

    // return value in previous render const previousValue = usePrevious(value); return <h1>Now: {value}, before: {previousValue}</h1>; } function usePrevious(value) { const ref = useRef(); useEffect(() => { ref.current = value; }); return ref.current; }
  38. Q: 犥盅 CLASS COMPONENT 䨝ᤩႣ࿶㻟牫 ▸ य़蟂獤 class ጱۑ胼᮷ݢ犥አ hooks

    䋿匍 ▸ getSnapshotBeforeUpdate 螭䷱磪 ▸ componentDidCatch 犖螭䷱磪 ▸ ֕犥盅ಅ磪 class ጱۑ胼᮷䨝磪䌘䛑ጱ hooks (or non-hooks) API ▸ ፓ獮ਥො䷱磪ᑏᴻ class component ጱ懯向 ▸ ॡग़膑 code牧犋ݢ胼犋ඪൔ ▸ ֕ฎ૶磭֦ݢ犥哴ᰁֵአ hooks
  39. Q: አ HOOKS ݢ犥玲դ HOC (HIGHER ORDER COMPONENT) 㻟牫 ▸

    盄ग़ HOC ᮷ݢ犥硬䌃౮ hooks ▸ ֕ฎ render bailout (shouldComponentUpdate) 犋ᤈ ▸ ContextProvider ፓ獮犖犋ᤈ
  40. Q: አ HOOKS ই֜䋿匍 SHOULD COMPONENT UPDATE ▸ React Lifecycle

    ▸ shouldComponentUpdate ࣁ render 獮牧ಅ犥䷱旰ဩ狶౮Ӟ 㮆 hook
  41. Q: አ HOOKS ই֜䋿匍 SHOULD COMPONENT UPDATE // React.PureComponent as

    HOC // skip rerender when props is shallowly equal to previous props const WrappedComponent = React.memo(Component); // custom compare function (prevProps, nextProps) => boolean const WrappedComponent = React.memo(Component, compareFunction);
  42. Q: አ HOOKS ই֜䋿匍 FORCE UPDATE ▸ አӞ㮆 useState ྯ稞

    +1 㬵蝨౮ rerender 疰অԧ ▸ ইຎ憽஑蠨牧ݢ犥۱౮Ӟ㮆 useForceUpdate ጱ hook
  43. Q: 犥盅 REDUX 䨝 GG 㻟牫 ▸ redux ๜蛪޾ React

    篷橕 ▸ Ӟ㮆क़蟂玕ጱ store 螭ฎ磪㰷独 ▸ redux ኞ眲羬磪盄ग़ middleware ▸ ౲战֦ᥝ㺔ጱ䛑扗ฎ react-redux
  44. Q: ᮎ犥盅 REACT-REDUX 䨝 GG 㻟牫 ▸ React ਥොጱమဩ物react-redux ݢ犥ڊ

    hooks: useRedux ▸ react-redux ጱమဩ物ݢ犥ڊ useRedux牧֕ฎ磪㺔氂 ▸ 蝈௏物react-redux ݝฎ಩ react 膏 redux Ԁ蚏㬵牧盄墋㻌 ▸ 䋿褬Ӥ react 膏 redux ᮷磪ᛔ૩ጱ life cycle牧ᥝ಩獋螲Ԁ 蚏㬵䋿褬Ӥ笕櫞ጱ ▸ react-redux 螭䒻֦狶ԧ盄ग़ᛔ㵕硳胼猻玕 ▸ 缛犥盅 React 䋿֢ଘᤈ玕牧蝡㮆㺔氂螭䨝虋ๅ櫞 ▸ react-redux ䷱磪ᮎ讕墋㻌
  45. Q: ᮎ犥盅 REACT-REDUX 䨝 GG 㻟牫 ▸ react-redux 㪔䷱磪泷Ӥ疰വڊ hooks

    粚 ▸ ቘమጱ䋿֢ොୗฎአ useReducer + useContext 䋿֢ useRedux ▸ ֕ useContext 愊硯 state 䨝磪硳胼㺔氂牧ፓ獮 react-redux ฎࣁ context 愊ल store牧砇蟴 subscription + force update ▸ ࣁ React ਥො究ਧই֜蒂ቘ useContext ጱ bailout 㺔氂獮 ض犋蚎蝡礿᪠
  46. Q: ᮎ犥盅 REACT-REDUX 䨝 GG 㻟牫 ▸ Roadmap (v6 →

    v7) ▸ ኧ Context 硯 state 硬ࢧ硯 store牧砇蟴 subscription + forceUpdate() ▸ 䨝ضአ React hooks 䋿֢ connect() (7.0.0-alpha) ▸ ٚവڊᛔ૩ጱ hooks useRedux() ▸ 奾抷物react-redux ጱ磧碝䋿֢犋ฎ㻌奈ጱ useContext + useReducer牧硳胼䨝穉斃অ牧ಅ犥ਙ螭犋䨝 GG
  47. Q: HOOKS 硳胼䨝穉斃癩㻟牫 ▸ 犋䨝牧ቘ抷Ӥ玱ᘒฎ穉斃অ牧ᴻԧ context 犥क़ ▸ ইຎݶ䰬妿螂猻玕物 ▸

    Hooks 硳胼䨝穉 class component অ ▸ ࢩ傶੝ധ class overhead ▸ Hooks 硳胼䨝穉 HOC অ ▸ ࢩ傶੝Ӟ䍅 component node ▸ useContext ፓ獮䷱磪 bailout ಋྦྷ牧襑ᥝग़۱Ӟ䍅 component牧޾ HOC 奾ຎӞ䰬
  48. Q: HOOKS 磪ߺ犚硳胼猻玕ಋྦྷ牫 ▸ ইຎಅ磪ጱ useState/useReducer call ࢧ㯽独᮷犋虋 (===)牧 㳷犋䨝

    rerender ▸ useMemo, useCallback ▸ React.memo() ▸ useEffect(…, inputs) ▸ useReducer ࢧ㯽ጱ dispatch function 犋䨝蝨౮ rerender
  49. Q: ֵአ HOOKS 磪ߺ犚硳胼ᵅᴟ牫 ▸ expensive setState initial value ▸

    setState lazy initialization ▸ inline function (breaks shouldComponentUpdate) ▸ useCallback ▸ expensive nodes ▸ React.memo() or useMemo() ▸ expensive useRef initial value ▸ ಋ㵕 set (誠誠)
  50. Q: ֵአ HOOKS 磪ߺ犚硳胼ᵅᴟ牫 ▸ useContext ▸ Ӟ㮆 component ݢ胼ݝ襑ᥝ

    context Ӟੜ蟂獤ጱ獉਻牧֕ context 独Ӟ虋疰䨝 rerender牧䷱旰ဩ bailout ▸ ਥො物TODO later ▸ 薹究旰ဩ ▸ አ React.memo() ग़۱Ӟ䍅
  51. Q: 傶Ջ讕ᥝ磪 HOOKS ▸ 懵玬 class component牧ࢩ傶磪盄ग़耬讨物 ▸ 襑ᥝ ES6牧ಅ犥஠殾ᥝ妿螂

    transpile ▸ class overhead ▸ class ጱ this 䌘犋ᆧ JS ጱՈ㬵藯犤Ոࢯజ牧֕傶ԧ薹究 inline function ጱ㺔氂݈襑ᥝ硽य़疑ࣁ constructor bind event listener ▸ side effect 犋਻ฃ狶ک separation of concern ▸ render ጱԆ薫ฎ function牧ݝฎ౯㮉襑ᥝ state 膏 side effect (life cycle)
  52. Q: 傶Ջ讕ᥝ磪 HOOKS ▸ 襑ᥝӞ㮆秚䯤ො׎ֵአᘏ᯿薟ֵአ state logic ▸ class mixin

    ▸ 蕣蝨ๅग़㺔氂 ▸ HOC (higher order component) ▸ 眜۱眜ग़䍅 ▸ wrapper component ▸ 傶ԧဳ獈ۑ胼ᘒ瞓ใ component tree
  53. Q: 傶Ջ讕ᥝ磪 HOOKS ▸ 犥 function component 傶Ԇ誢 ▸ 犋硬虋

    component tree ▸ ๅ਻ฃ狶ک separation of concern ▸ What is the prior art for hooks
  54. Q: 傶Ջ讕 HOOKS 胙盅ฎ ARRAY 犋ฎ MAP牫 ▸ 虏ྯ㮆 hooks

    ԏ樌ݢ犥ਠ獊加缏 ▸ why-do-hooks-rely-on-call-order ▸ why-isnt-x-a-hook
  55. Q: 疰ቘ抷Ӥ㬵藯牧HOOKS ک皈ฎՋ讕牫 ▸ Function component + hooks 
 碪犋ฎ

    functional programming 犖犋ฎᇔկ疩ݻ ▸ Hooks ጱ API 癲㬵Ӟ㮆碝ጱ design pattern ▸ Hidden context aligned by call order ▸ Reactive programming on state logic
  56. REACTIVE PROGRAMMING ▸ Imperative (瞲犤ୗ) vs declarative (ਯޞୗ) ▸ ࣁ瞲犤ୗ承᥺Ӿ

    c = a + b ฎ assignment ▸ ࣁਯޞୗ承᥺Ӿ c = a + b ฎ binding c = a + b
  57. REACTIVE PROGRAMMING ▸ Imperative (瞲犤ୗ) vs declarative (ਯޞୗ) ▸ JS

    ฎ imperative 承᥺ ▸ React 䒻֦蒂ቘധ rendering lifecycle 膏 optimization ▸ ኸ妔֦䌃蚏㬵眤憽盄矑蜱 declarative ጱ render function ▸ 疪ٌ function component ݈穉 class component ๅ奈 ({count}) => <span>{count}</span>
  58. REACTIVE PROGRAMMING ▸ Imperative (瞲犤ୗ) vs declarative (ਯޞୗ) ▸ JS

    ฎ imperative 承᥺ ▸ React 䒻֦蒂ቘധ rendering lifecycle 膏 optimization ▸ ኸ妔֦䌃蚏㬵眤憽盄矑蜱 declarative ጱ render function ▸ 疪ٌ function component ݈穉 class component ๅ奈 ▸ Hooks API 犖ฎአ imperative JS 䋿֢ڊ觊犲 declarative ጱ 纷ୗૡ萬 const [value, setValue] = useState(0)
  59. REACTIVE PROGRAMMING ▸ ইຎ䌃 component ጱ碻狡牧ᥝమ猟碉㮆螀֢秚ګ牧䨝盄ᔴ ▸ ౯㮉ݝᥝᘍ眾 state/props ই֜䌘ᆙک

    DOM tree 疰অԧ ▸ ು虡玕 ▸ ֕缛کڊ bug ౲硳胼粁篂ጱ碻狡 ▸ ౯㮉ᥝ胼䄪ԧ薹ਙ胙盅螀֢秚ګ ▸ ು虡佒笙 ({count}) => <span>{count}</span>
  60. REACTIVE PROGRAMMING ▸ ইຎ䌃 async/await ጱ碻狡牧ᥝమ猟碉㮆螀֢秚ګ牧䨝盄ᔴ ▸ ౯㮉ݝᥝᘍ眾纷ୗ䨝ই֜᪒کӞ܎䥁樄ٚ矑ࢧ㬵疰অԧ ▸ ು虡玕

    ▸ ֕缛کڊ bug ౲硳胼粁篂ጱ碻狡 ▸ ౯㮉ᥝ胼䄪ԧ薹ਙ胙盅螀֢秚ګ ▸ ು虡佒笙 let value = await fn();
  61. REACTIVE PROGRAMMING ▸ ইຎ䌃 hooks ጱ碻狡牧ᥝమ猟碉㮆螀֢秚ګ牧䨝盄ᔴ ▸ ౯㮉ݝᥝᘍ眾 state 膏

    side effect 䨝ই֜ڊ匍疰অԧ ▸ ು虡玕 ▸ ֕缛کڊ bug ౲硳胼粁篂ጱ碻狡 ▸ ౯㮉ᥝ胼䄪ԧ薹ਙ胙盅螀֢秚ګ ▸ ು虡佒笙 const [value, setValue] = useState(0)
  62. REACTIVE PROGRAMMING ▸ function component ▸ declarative way of writing

    view ▸ hooks ▸ declarative way of writing state logic
  63. Q: ౯䛑扗ᥝአ HOOKS 㻟牫 ▸ Hooks API ฎӞ圵碝誢涢 ▸ 䌃

    custom hooks 盄磪蚕 ▸ ݢ犥ࣁੜ䌕礯牏碝䌕礯牏౲䌕礯愊穉斃加缏ጱੜ玟璸ሻሻ፡
  64. Q: 磪ԧ USE REDUCER牧౯䛑扗ᥝ硯祌 REDUX 㻟牫 ▸ redux ䷱磪ᮎ讕অ瞥 ▸

    蝫 react-redux ጱՈ᮷൥犋ਧ useReducer + useContext ጱ 硳胼㺔氂ԧ ▸ 犢㮉䨝ฎ磧盠വڊ蝢薹ጱՈ牧ಅ犥 follow 犢㮉疰䌘ԧ ▸ 缛犢㮉വڊ useRedux牧֦犖疰犋አ硯祌 redux ԧ
  65. Q: ౯䛑扗ᥝࣁ PRODUCTION Ӥአ HOOKS 㻟牫 ▸ Hooks API 螭磪Ӟ犚

    bug 膏犋᪃ԏ蒂 ▸ Context API 螭䷱磪伛猋অ螕䛑 hooks ▸ ䷱磪ՈᎣ螇 hooks 櫝 production ready 螭磪ग़螐 ▸ ԧ薹眜ग़奞℄牧觓檺眜犵
  66. 皤֐褂捝 ▸ ਥො guide ▸ Dan Abramov ጱ blog ▸

    React issue list ▸ Hooks implementation