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

Functioning in React: A Deep-Dive into useState

Functioning in React: A Deep-Dive into useState

The State Hook is now a core part of React. But what does it mean for a function to have state? This talk explores this question, touching on the history of state, the source code behind the hook, and the impact stateful functions have on the code we write.

A9689bb4f705b8bede56deddf66c87ef?s=128

Jake Worth

October 03, 2019
Tweet

Transcript

  1. Functioning in React: A Deep-Dive into useState Jake Worth, Hashrocket

  2. Ponzi Scheme @jwworth 2

  3. "[I]f he doesn't understand something, he just asks you. He

    doesn't care if he sounds foolish... he will ask the most obvious question without any sort of concern about it... so he asks lots and lots of 'dumb,' in the best sense of that word, questions. He'll say to someone, 'I don't understand. Explain that to me.' He'll just keep asking questions until he gets it right." — Malcolm Gladwell1 1 Ferriss 2016, 573. @jwworth 3
  4. ! ------|------ @jwworth 4

  5. ! ------|---- - @jwworth 5

  6. » ! Jake Worth / @jwworth » " Hashrocket »

    # Today I Learned » $ https://www.jakeworth.com/ @jwworth 6
  7. The Tower of Abstractions @jwworth 7

  8. useState @jwworth 8

  9. Who is this talk for? @jwworth 9

  10. Disclaimer @jwworth 10

  11. State @jwworth 11

  12. Pitch: Understanding useState will make us better developers! @jwworth 12

  13. Agenda 1. History of State 2. State Hooks Deep-Dive 3.

    Hooks In My Code? @jwworth 13
  14. 1. History of State @jwworth 14

  15. History of State: CS "Stateful means the computer or program

    keeps track of the state of interaction, usually by setting values in a storage field designated for that purpose. Stateless means there is no record of previous interactions and each interaction request has to be handled based entirely on information that comes with it."2 2 Whatis.com 2019. @jwworth 15
  16. History of State: CS "Stateful means the computer or program

    keeps track of the state of interaction, usually by setting values in a storage field designated for that purpose. Stateless means there is no record of previous interactions and each interaction request has to be handled based entirely on information that comes with it."2 2 Whatis.com 2019. @jwworth 16
  17. History of State: CS » Stateless interaction: HTTP » Stateful

    interaction: Browser & localStorage » Imperative programming languages: JavaScript @jwworth 17
  18. History of State: CS "In computer science, imperative programming is

    a programming paradigm that uses statements that change a program's state."3 3 Wikipedia 2019. @jwworth 18
  19. History of State: React » ES3 module pattern » ES6

    component classes » Stateless functional components » Class-fields syntax » Stateful functional components (Hooks) @jwworth 19
  20. History of State: React Sandbox: https://codesandbox.io/s/react-state-history-bwh2x @jwworth 20

  21. History of State: React 0.13 // ES3 module pattern function

    PirateShip(initialProps) { return { state: { cannonsCount: 0 }, render: function() { return <div>{this.state.cannonsCount} cannons</div>; }, }; } @jwworth 21
  22. History of State: React 0.13 // ES6 component classes class

    PirateShip extends React.Component { constructor(props) { super(props); this.state = { cannonsCount: 0 }; } render() { return <div>{this.state.cannonsCount} cannons</div>; } } @jwworth 22
  23. History of State: React 0.13 // Updater function this.setstate((state, props)

    => { return { cannonsCount: state.cannonsCount + 1 }; }); // First-argument object this.setstate({ cannonsCount: 100 }); @jwworth 23
  24. History of State: React 0.14 "In idiomatic react code, most

    of the components you write will be stateless."4 4 Alpert "React v0.14" 2015. @jwworth 24
  25. History of State: React 0.14 // ES6 arrow function var

    PirateShip = props => { var cannonsCount = props.cannonsCount; return <div>{cannonsCount} cannons</div>; }; @jwworth 25
  26. History of State: React 0.14 & ES6 // Class-fields syntax

    class PirateShip extends React.Component { state = { cannonsCount: 0 }; render() { return <div>{this.state.cannonsCount} cannons</div>; } } @jwworth 26
  27. History of State: React 16.8 // useState function PirateShip() {

    const [cannonsCount, setCannonsCount] = useState(0); return <div>{cannonsCount} cannons</div> } @jwworth 27
  28. History of State: React 16.8 // useState w/ multiple slices

    function PirateShip() { const [cannonsCount, setCannonsCount] = useState(0); const [anchored, setAnchored] = useState(false); // return JSX } @jwworth 28
  29. History of State: React 16.8 // useState function PirateShip() {

    const [cannonsCount, setCannonsCount] = useState(0); // return JSX } @jwworth 29
  30. 2. State Hooks Deep-Dive @jwworth 30

  31. State Hooks Deep-Dive: Below » ! Multiple packages » "

    Type-safety » # Dependency injection » $ Interesting comments » % Leaps of faith @jwworth 31
  32. State Hooks Deep-Dive: SHA React SHA: 34aaec6f908e85d56cbc510677bc1c85d87aa57b @jwworth 32

  33. // Our code function PirateShip() { const [cannonscount, setCannonsCount] =

    useState(0); // return JSX } @jwworth 33
  34. // Our code import React, { useState } from 'react';

    // function PirateShip() { const [cannonscount, setCannonsCount] = useState(0); // return JSX } @jwworth 34
  35. State Hooks Deep-Dive: Split » React 0.14 Package split: react

    & react-dom » Renderers: react-dom, react-dom/server, react-native, react- test-renderer, react-art @jwworth 35
  36. // packages/react/index.js const React = require('./src/React'); // TODO: decide on

    the top-level export form. // This is hacky but makes it work with both // Rollup and Jest. ! module.exports = React.default || React; @jwworth 36
  37. // packages/react/src/React.js import { useState } from './ReactHooks'; const React

    = { useState, }; export default React; @jwworth 37
  38. // packages/react/src/React.js import { useState } from './ReactHooks'; const React

    = { useState, __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: ReactSharedInternals, // }; export default React; @jwworth 38
  39. // packages/react/src/React.js import { useState } from './ReactHooks'; const React

    = { useState, }; export default React; @jwworth 39
  40. // packages/react/src/ReactHooks.js export function useState<S>(initialState: (() => S) | S)

    { const dispatcher = resolveDispatcher(); return dispatcher.useState(initialState); } @jwworth 40
  41. None
  42. // packages/react/src/ReactHooks.js export function useState<S>(initialState: (() => S) | S)

    { const dispatcher = resolveDispatcher(); return dispatcher.useState(initialState); // } @jwworth 42
  43. "[T]he base class setState() implementation has been an illusion all

    along. It doesn't do anything except forwarding the call to the current renderer. And [the] useState Hook does exactly the same thing." — Dan Abramov5 5 Abramov "How Does setState Know What to Do?" 2018. @jwworth 43
  44. // packages/react/src/ReactHooks.js import ReactCurrentDispatcher from './ReactCurrentDispatcher'; function resolveDispatcher() { const

    dispatcher = ReactCurrentDispatcher.current; return dispatcher; } @jwworth 44
  45. // packages/react/src/ReactCurrentDispatcher.js import type {Dispatcher} from 'react-reconciler/src/ReactFiberHooks'; const ReactCurrentDispatcher =

    { current: (null: null | Dispatcher), }; export default ReactCurrentDispatcher; @jwworth 45
  46. > const immutable = { permanent: "don't update me" }

    undefined > immutable["permanent"] = 'uh oh' 'uh oh' > immutable { permanent: 'uh oh' } @jwworth 46
  47. // packages/react/src/ReactCurrentDispatcher.js import type {Dispatcher} from 'react-reconciler/src/ReactFiberHooks'; const ReactCurrentDispatcher =

    { current: (null: null | Dispatcher), // }; export default ReactCurrentDispatcher; @jwworth 47
  48. "[T]he base class setState() implementation has been an illusion all

    along. It doesn't do anything except forwarding the call to the current renderer." — Dan Abramov5 5 Abramov "How Does setState Know What to Do?" 2018. @jwworth 48
  49. // packages/react-dom/src/server/ReactPartialRenderer.js import { Dispatcher, } from './ReactPartialRendererHooks'; ReactCurrentDispatcher =

    ReactSharedInternals.ReactCurrentDispatcher; ReactCurrentDispatcher.current = Dispatcher; @jwworth 49
  50. // packages/react-dom/src/server/ReactPartialRendererHooks.js export const Dispatcher: DispatcherType = { useState, };

    @jwworth 50
  51. // packages/react-dom/src/server/ReactPartialRendererHooks.js export function useState<S>( initialState: (() => S) |

    S, ): [S, Dispatch<BasicStateAction<S>>] { return useReducer(basicStateReducer, (initialState: any)); } export const Dispatcher: DispatcherType = { useState, }; @jwworth 51
  52. // packages/react-dom/src/server/ReactPartialRendererHooks.js // useReducer (abridged) workInProgressHook = createWorkInProgressHook(); workInProgressHook.memoizedState =

    state; const dispatch: Dispatch<A> = (queue.dispatch: any); return [workInProgressHook.memoizedState, dispatch]; @jwworth 52
  53. // packages/react-dom/src/server/ReactPartialRendererHooks.js function createHook(): Hook { return { memoizedState: null,

    queue: null, next: null, }; } @jwworth 53
  54. // Our code const [cannonscount, setCannonsCount] = useState(0); @jwworth 54

  55. // Our code const [cannonscount, setCannonsCount] = useState(0); ‑ const

    [WIPHookMemoizedState, dispatch] = useState(0); @jwworth 55
  56. State Hooks Deep-Dive: Resurfacing » React checks types and creates

    an interface for a dispatcher » The renderer nullifies and sets a real dispatcher » The dispatcher returns an array of memoized state and a setter function » Rendering and reconciliation occurs @jwworth 56
  57. 3. Hooks In My Code? @jwworth 57

  58. Hooks are great and you should use them! @jwworth 58

  59. Hooks are everywhere! @jwworth 59

  60. Hooks solve problems! @jwworth 60

  61. State management is important! @jwworth 61

  62. Should I refactor my existing components to use hooks? @jwworth

    62
  63. Hooks are great and you should use them! @jwworth 63

  64. Conclusion @jwworth 64

  65. Thank you! Jake Worth / @jwworth @jwworth 65

  66. Further Reading » "RFC: React Hooks", Reactjs RFCs, accessed September,

    2019, https://github.com/reactjs/rfcs/pull/68. » Abramov, Dan. 2018. "How Does setState Know What to Do?". Overreacted.io, December 9, 2018. https://overreacted.io/how-does-setstate-know-what-to-do/. » Abramov, Dan. 2018. "Why Do We Write super(props)?". Overreacted.io, November 30, 2018. https://overreacted.io/why-do-we-write-super-props/. » Albert, Sophie. 2015. "React v0.14". React.js Blog, October 7, 2015. https://reactjs.org/blog/2015/10/07/react-v0.14.html. » Alpert, Sophie. 2015. "React's Package Split". React.js Blog. July 3, 2015. https://reactjs.org/blog/2015/07/03/react-v0.14-beta-1.html#two-packages. » Clark, Andrew. 2016. "React Fiber Architecture". GitHub Gist. July 18, 2016. https://github.com/acdlite/react-fiber-architecture/blob/master/README.md. » Clark, Lin. 2017. "A Cartoon Intro to Fiber". Filmed at React Conf 2017, San Francisco, CA. Video. https://youtu.be/ZCuYPiUIONs. » Cowan, Paul. 2019. "Frustrations With Hooks". LogRocket Blog, September 9, 2019. https://blog.logrocket.com/frustrations-with-react-hooks/. » Dhuyvetters, Geoffrey. 2016. "What is React Fiber? And how can I try it out today?". GitHub Gist, December 20, 2016. https://gist.github.com/duivvv/2ba00d413b8ff7bc1fa5a2e51c61ba43. » Ehrenberg, Daniel and Morrison, Jeff. "Class field declarations for JavaScript". ECMT TC39, accessed September, 2019, https://github.com/tc39/proposal-class-fields. » Ferriss, Tim. 2016. Tools of Titans: The Tactics, Routines, and Habits of Billionaires, Icons, and World-Class Performers . New York: Houghton Mifflin Harcourt. » Giamir Buoncristiani, Giamir. 2017. "What is React Fiber?". Giamir.com. April 23, 2017. https://giamir.com/what-is-react-fiber. » Iffland, David. 2017. "React Fiber: A Closer Look at the New Engine of React". May 1, 2017. https://www.infoq.com/news/2017/05/react-fiber-closer-look/. » Markbåge, Sebastian. 2015. "React v0.13.0 Beta 1". React.js Blog. January, 2015. https://reactjs.org/blog/2015/01/27/react-v0.13.0-beta-1.html. » McCracken, Harry. 2014. "This 1981 Computer Magazine Cover Explains Why We're So Bad at Tech Predictions". Time Magazine, April 14, 2014, https://time.com/60505/this-1981-computer-magazine- cover-explains-why-were-so-bad-at-tech-predictions/. » Rouse, Margaret. s.v. "stateless". Whatis.com. Accessed September, 2019, https://whatis.techtarget.com/definition/stateless. » Flow Documentation, s.v. "Generics", accessed September 2019, https://flow.org/en/docs/types/generics/. » Flow Documentation, s.v. "Importing and Exporting Types", accessed September 2019, https://flow.org/en/docs/types/modules/#importing-and-exporting-types-. » Flow Documentation, s.v. "Type Aliases", accessed September 2019, https://flow.org/en/docs/types/aliases/. » Wikipedia, s.v. "Imperative Programming", accessed September 2019, https://en.wikipedia.org/wiki/Imperative_programming. @jwworth 66