$30 off During Our Annual Pro Sale. View Details »

🇮🇱 React Next 2022

🇮🇱 React Next 2022

ℹ️ Inside Fiber: the in-depth overview you wanted a TLDR for

We'll have an in-depth overview of the important concepts behind reconciliation and React Fiber. Then, we'll explore how React uses this algorithm and go through a few magic words we hear a lot, like coroutines, continuations, generators, and algebraic effects—and see how they all relate to React.

Matheus Albuquerque

June 28, 2022
Tweet

More Decks by Matheus Albuquerque

Other Decks in Technology

Transcript

  1. Hello, React Next 🙋 🇮🇱 🌎 INSIDE FIBER: THE IN-DEPTH

    OVERVIEW YOU WANTED A TLDR FOR • THE 28TH OF JUNE, 2022.
  2. MATHEUS ALBUQUERQUE INSIDE FIBER THE IN-DEPTH OVERVIEW YOU WANTED A

    TLDR FOR
  3. I’M MATHEUS 🙋 ↝ @YTHECOMBINATOR ON THE WEB ↝ SR.

    SOFTWARE ENGINEER @ MEDALLIA ↝ MENTOR @ TECHLABS BERLIN
  4. ⚠ DISCLAIMER ⚠

  5. 1. REACT SOURCE CODE IS CONSTANTLY CHANGING, AND SOME THOUGHTS

    ARE SPECULATIVE
  6. 2. MAYBE THIS TALK WON’T BE 100% WHAT YOU’D CALL

    A TLDR
  7. 2. MAYBE THIS TALK WON’T BE 100% WHAT YOU’D CALL

    A TLDR 🤯= HUGE CONTENT PAYLOAD / DESERVES FURTHER DISCUSSIONS AFTER THE SESSION
  8. A bit of context INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU

    WANTED A TLDR FOR
  9. HTTPS://GITHUB.COM/ MACABEUS/JS-PROPOSAL-ALGEBRAIC-EFFECTS

  10. CONTINUATIONS ALGEBRAIC EFFECTS COROUTINES FIBERS THREADS GENERATORS

  11. ALGEBRAIC EFFECTS COROUTINES FIBERS GENERATORS CONTINUATIONS THREADS

  12. Fiber(s) INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

    FOR
  13. function add(x,y) { const result = x + y; return

    result; } add(2, 2)
  14. let frame: Frame = { return: frame, fn: add, parameters:

    [2, 2], localVariables: { result: 4, }, }
  15. let frame: Frame = { return: frame, fn: add, parameters:

    [2, 2], localVariables: { result: 4, }, } let fiber: Fiber = { return: fiber, component: Avatar, props: { id: 4 }, state: { isLoaded: true, }, }
  16. ↝ FIBER ARCHITECTURE ⇢ REACT-SPECIFIC IMPLEMENTATION OF A CALL-STACK-LIKE MODEL

    WHERE REACT HAS FULL CONTROL OF SCHEDULING WHAT SHOULD BE DONE ↝ FIBER ⇢ A STACK FRAME FOR A REACT COMPONENT
  17. Fibers as Units of Work INSIDE FIBER: THE IN-DEPTH OVERVIEW

    YOU WANTED A TLDR FOR
  18. DURING RECONCILIATION, DATA FROM EVERY REACT ELEMENT RETURNED FROM THE

    RENDER METHOD IS MERGED INTO THE TREE OF FIBER NODES. DEPENDING ON THE TYPE OF A REACT ELEMENT THE FRAMEWORK NEEDS TO PERFORM DIFFERENT ACTIVITIES. EACH ELEMENT IS CONVERTED INTO A FIBER NODE THAT DESCRIBES THE WORK THAT NEEDS TO BE DONE. ONCE A TEMPLATE GOES THROUGH THE JSX COMPILER, YOU END UP WITH A BUNCH OF REACT ELEMENTS.
  19. DURING RECONCILIATION, DATA FROM EVERY REACT ELEMENT RETURNED FROM THE

    RENDER METHOD IS MERGED INTO THE TREE OF FIBER NODES. DEPENDING ON THE TYPE OF A REACT ELEMENT THE FRAMEWORK NEEDS TO PERFORM DIFFERENT ACTIVITIES. EACH ELEMENT IS CONVERTED INTO A FIBER NODE THAT DESCRIBES THE WORK THAT NEEDS TO BE DONE. ONCE A TEMPLATE GOES THROUGH THE JSX COMPILER, YOU END UP WITH A BUNCH OF REACT ELEMENTS.
  20. DEPENDING ON THE TYPE OF A REACT ELEMENT THE FRAMEWORK

    NEEDS TO PERFORM DIFFERENT ACTIVITIES. EACH ELEMENT IS CONVERTED INTO A FIBER NODE THAT DESCRIBES THE WORK THAT NEEDS TO BE DONE. ONCE A TEMPLATE GOES THROUGH THE JSX COMPILER, YOU END UP WITH A BUNCH OF REACT ELEMENTS. DURING RECONCILIATION, DATA FROM EVERY REACT ELEMENT RETURNED FROM THE RENDER METHOD IS MERGED INTO THE TREE OF FIBER NODES.
  21. EACH ELEMENT IS CONVERTED INTO A FIBER NODE THAT DESCRIBES

    THE WORK THAT NEEDS TO BE DONE. ONCE A TEMPLATE GOES THROUGH THE JSX COMPILER, YOU END UP WITH A BUNCH OF REACT ELEMENTS. DURING RECONCILIATION, DATA FROM EVERY REACT ELEMENT RETURNED FROM THE RENDER METHOD IS MERGED INTO THE TREE OF FIBER NODES. DEPENDING ON THE TYPE OF A REACT ELEMENT THE FRAMEWORK NEEDS TO PERFORM DIFFERENT ACTIVITIES.
  22. ONCE A TEMPLATE GOES THROUGH THE JSX COMPILER, YOU END

    UP WITH A BUNCH OF REACT ELEMENTS. DURING RECONCILIATION, DATA FROM EVERY REACT ELEMENT RETURNED FROM THE RENDER METHOD IS MERGED INTO THE TREE OF FIBER NODES. DEPENDING ON THE TYPE OF A REACT ELEMENT THE FRAMEWORK NEEDS TO PERFORM DIFFERENT ACTIVITIES. A UNIT OF WORK. EACH ELEMENT IS CONVERTED INTO A FIBER NODE THAT DESCRIBES THE WORK THAT NEEDS TO BE DONE.
  23. ONCE A TEMPLATE GOES THROUGH THE JSX COMPILER, YOU END

    UP WITH A BUNCH OF REACT ELEMENTS. DURING RECONCILIATION, DATA FROM EVERY REACT ELEMENT RETURNED FROM THE RENDER METHOD IS MERGED INTO THE TREE OF FIBER NODES. DEPENDING ON THE TYPE OF A REACT ELEMENT THE FRAMEWORK NEEDS TO PERFORM DIFFERENT ACTIVITIES. A UNIT OF WORK. EACH ELEMENT IS CONVERTED INTO A FIBER NODE THAT DESCRIBES THE WORK THAT NEEDS TO BE DONE. AND THAT MAKES IT A CONVENIENT WAY TO TRACK, SCHEDULE, PAUSE AND ABORT THE WORK.
  24. Visualizing Units of Work INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU

    WANTED A TLDR FOR
  25. 🤓💻 EXPERIMENT #1 INSPECTING ELEMENTS

  26. None
  27. None
  28. let fiberNode = fiberRoot.current; let fibersMap = new Map(); while

    (fiberNode) { if (fiberNode.stateNode ! = = null) { fibersMap.set(fiberNode.stateNode, fiberNode); } if (fiberNode.child === null) { while (fiberNode ! = = null & & fiberNode.sibling === null) { fiberNode = fiberNode.return; } fiberNode = fiberNode?.sibling; continue; } fiberNode = fiberNode.child; }
  29. let fiberNode = fiberRoot.current; let fibersMap = new Map(); while

    (fiberNode) { if (fiberNode.stateNode ! = = null) { fibersMap.set(fiberNode.stateNode, fiberNode); } if (fiberNode.child === null) { while (fiberNode ! = = null & & fiberNode.sibling === null) { fiberNode = fiberNode.return; } fiberNode = fiberNode?.sibling; continue; } fiberNode = fiberNode.child; } 🤯
  30. None
  31. HTTPS://YOUTU.BE/ZCUYPIUIONS HTTPS://GITHUB.COM/FACEBOOK/REACT/BLOB/MAIN/ PACKAGES/REACT-RECONCILER/SRC/REACTINTERNALTYPES.JS

  32. HTTPS://YOUTU.BE/ZCUYPIUIONS HTTPS://GITHUB.COM/FACEBOOK/REACT/BLOB/MAIN/ PACKAGES/REACT-RECONCILER/SRC/REACTWORKTAGS.JS

  33. Manipulating Units of Work INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU

    WANTED A TLDR FOR
  34. 🙋✋ QUESTION #1 HAVE YOU EVER HEARD ABOUT HOMOICONICITY?

  35. (let [x 1] (inc x)) ; = > 2

  36. PERFORMS A TEMPORARY BINDING (BINDS X TO THE VALUE 1)

    (let [x 1] (inc x)) ; = > 2
  37. INCREMENTS X TO GIVE THE RETURN VALUE OF 2 (let

    [x 1] (inc x)) ; = > 2
  38. IT CAN BE THOUGHT OF AS A LIST WITH THREE

    ELEMENTS ↝ A SYMBOL NAMED LET ↝ A VECTOR WITH TWO ELEMENTS ↝ A SYMBOL NAMED X ↝ AND AN INTEGER ↝ A LIST WITH TWO ELEMENTS ↝ A SYMBOL NAMED INC ↝ AND A SYMBOL NAMED X
  39. “…HOMOICONICITY IS A PROPERTY OF SOME PROGRAMMING LANGUAGES IN WHICH

    THE CODE USED TO EXPRESS A PROGRAM IS WRITTEN USING THE DATA STRUCTURES OF THAT LANGUAGE. 🤯
  40. CODE = DATA “…HOMOICONICITY IS A PROPERTY OF SOME PROGRAMMING

    LANGUAGES IN WHICH THE CODE USED TO EXPRESS A PROGRAM IS WRITTEN USING THE DATA STRUCTURES OF THAT LANGUAGE. 🤯
  41. ↝ REACT ELEMENTS ARE JUST DATA ↝ JUST LIKE IN

    LISP, REACT COMPONENTS CAN MANIPULATE THEIR CHILDREN AND RETURN COMPLETELY DIFFERENT THINGS
  42. 🤓💻 EXPERIMENT #2 PATTERN MATCHING IN REACT

  43. None
  44. / / . . . export function isWhen<Shape extends {}>(

    child: ElementWithMetadataUnion<Shape> ): child is ElementWithMetadata<WhenProps<Shape > > { return child.element.type === When; } / / . . . export function nodesToElementWithMetadata<Shape extends {}>( children: ReactNode ) { return Children.toArray(children).map((element, idx) = > ({ element: element, position: idx, })) as Array<ElementWithMetadata<Shape > > ; } / / . . .
  45. const supportsSensor = () = > Boolean(window.AmbientLightSensor); const AmbientLight =

    React.lazy(() = > import("./AmbientLight")); const Fallback = React.lazy(() = > import("./Fallback")); export default function MyComponent() { const { Match, When, Otherwise } = usePatternMatch(); return ( <Suspense fallback="Loading"> <Match> <When predicate={supportsSensor}> <AmbientLight /> </When> <Otherwise> <Fallback /> </Otherwise> </Match> </Suspense> ); }
  46. const supportsSensor = () = > Boolean(window.AmbientLightSensor); const AmbientLight =

    React.lazy(() = > import("./AmbientLight")); const Fallback = React.lazy(() = > import("./Fallback")); export default function MyComponent() { const { Match, When, Otherwise } = usePatternMatch(); return ( <Suspense fallback="Loading"> <Match> <When predicate={supportsSensor}> <AmbientLight /> </When> <Otherwise> <Fallback /> </Otherwise> </Match> </Suspense> ); } PATTERN MATCHING + REACT.SUSPENSE + REACT.LAZY() = USERS DOWNLOAD ONLY THE ACTUAL COMPONENT BUNDLE THAT MATCHES A CONDITION
  47. const supportsSensor = () = > Boolean(window.AmbientLightSensor); const AmbientLight =

    React.lazy(() = > import("./AmbientLight")); const Fallback = React.lazy(() = > import("./Fallback")); export default function MyComponent() { const { Match, When, Otherwise } = usePatternMatch(); return ( <Suspense fallback={"Loading"}> <Match> <When predicate={supportsSensor}> <AmbientLight /> </When> <Otherwise> <Fallback /> </Otherwise> </Match> </Suspense> ); } PATTERN MATCHING + REACT.SUSPENSE + REACT.LAZY() = USERS DOWNLOAD ONLY THE ACTUAL COMPONENT BUNDLE THAT MATCHES A CONDITION MANIPULATING BASED ON ELEMENTS DATA.
  48. HTTPS://GITHUB.COM/ YTHECOMBINATOR/REACT-MATCHEZ

  49. Coroutines INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

    FOR
  50. None
  51. 1. A GENERATOR (PRODUCER) THAT CAN ALSO CONSUME VALUES.

  52. 1. A GENERATOR (PRODUCER) THAT CAN ALSO CONSUME VALUES. ↝

    JAVASCRIPT GENERATORS CAN CONSUME VALUES ↝ BY THIS DEFINITION, THEY ARE COROUTINES
  53. 2. A GENERATOR THAT CAN RESOLVE ASYNCHRONOUS VALUES, LIKE ASYNC/AWAIT.

  54. 2. ↝ THIS IS THE MOST COMMON MEANING OF “COROUTINE”

    IN THE JAVASCRIPT WORLD ↝ WE HAD CO AND BLUEBIRD, WHICH HAD ASYNC/AWAIT IMPLEMENTATIONS BASED ON GENERATORS A GENERATOR THAT CAN RESOLVE ASYNCHRONOUS VALUES, LIKE ASYNC/AWAIT.
  55. 3. A GENERATOR THAT CAN YIELD WITH A STACKFUL CONTINUATION

  56. 3. ↝ = DEEP AWAIT ↝ WITH SUSPENSE, WE CAN

    PAUSE RECONCILIATION AT ANY DEPTH A GENERATOR THAT CAN YIELD WITH A STACKFUL CONTINUATION 🤯
  57. Fibers CONTROL IS PASSED TO A SCHEDULER WHICH DETERMINES WHAT

    TO RUN NEXT ↝ = CONTROLLED AT THE LEVEL OF THE OPERATING SYSTEM OR FRAMEWORK ↝ E.G. NODE.JS EVENT LOOP
  58. Coroutines CONTROL IS PASSED TO THE CALLER AND HANDLED BY

    APPLICATION CODE Fibers CONTROL IS PASSED TO A SCHEDULER WHICH DETERMINES WHAT TO RUN NEXT
  59. Coroutines & React INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED

    A TLDR FOR
  60. COROUTINES APPEARED WHEN WORK ON FIBER WAS FIRST GOING AS

    A SPECIFIC COMPONENT TYPE. THE IDEA BEHIND COROUTINES — AS OPPOSED TO FIBERS — WAS TO GIVE COMPONENTS EXPLICIT CONTROL OVER YIELDING AND RESUMPTION.
  61. HTTPS://GITHUB.COM/FACEBOOK/REACT/ PULL/6859

  62. ↝ COROUTINES PER SI IN REACT NO LONGER EXIST. ↝

    IT WILL BE FASCINATING TO SEE WHAT FORM COROUTINES TAKE WHEN THEY RETURN TO REACT FIBER.
  63. Coroutines & Concurrent React INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU

    WANTED A TLDR FOR
  64. HTTPS://WWW.YOUTUBE.COM/WATCH? V=NLF0N9SACD4

  65. function resourcefulOperation(value: number) { let newValue = String(value); for (let

    i = 0; i < 1000000; i++) { newValue = `${value} + ${i} = ${value + i}`; } return newValue; } function ResourcefulComponent(props: { value: number }) { const { value } = props; const result = resourcefulOperation(value); return <p>{result}</p>; }
  66. None
  67. 🤓💻 EXPERIMENT #3 BUILDING A COROUTINES-BASED SCHEDULER

  68. function resourcefulOperation(value: number) { let newValue = String(value); for (let

    i = 0; i < 1000000; i++) { newValue = `${value} + ${i} = ${value + i}`; } return newValue; } function ResourcefulComponent(props: { value: number }) { const { value } = props; const result = resourcefulOperation(value); return <p>{result}</p>; }
  69. function* resourcefulOperation(value: number) { let newValue = String(value); while (true)

    { yield; for (let i = 0; i < 1000000; i++) { newValue = `${value} + ${i} = ${value + i}`; } return newValue; } } const initialValue = 0; const scheduler = new Scheduler(resourcefulOperation, initialValue); function ResourcefulComponent(props: { value: number }) { const { value } = props; const result = scheduler.performUnitOfWork(value); return <p>{result}</p>; }
  70. function* resourcefulOperation(value: number) { let newValue = String(value); while (true)

    { yield; for (let i = 0; i < 1000000; i++) { newValue = `${value} + ${i} = ${value + i}`; } return newValue; } } const initialValue = 0; const scheduler = new Scheduler(resourcefulOperation, initialValue); function ResourcefulComponent(props: { value: number }) { const { value } = props; const result = scheduler.performUnitOfWork(value); return <p>{result}</p>; } / / PROMOTED TO A GENERATOR. / / YIELDING INSIDE AN INFINITE LOOP. / / DOING CONCURRENT STUFF.
  71. None
  72. enum SchedulerState { IDLE = "IDLE", PENDING = "PENDING", DONE

    = "DONE", } class Scheduler<T> { state: SchedulerState; result: T; worker: (data: T) = > Generator; iterator: Generator; constructor(worker: (data: T) = > Generator, initialResult: T) { this.state = SchedulerState.IDLE; this.worker = worker; this.result = initialResult; } performUnitOfWork(data: T) { switch (this.state) { case "IDLE": this.state = SchedulerState.PENDING; this.iterator = this.worker(data); throw Promise.resolve(); case "PENDING": const { value, done } = this.iterator.next(); if (done) { this.result = value; this.state = SchedulerState.DONE; return value; } throw Promise.resolve(); case "DONE": this.state = SchedulerState.IDLE; return this.result; } } } 🤯
  73. enum SchedulerState { IDLE = "IDLE", PENDING = "PENDING", DONE

    = "DONE", } class Scheduler<T> { state: SchedulerState; result: T; worker: (data: T) = > Generator; iterator: Generator; constructor(worker: (data: T) = > Generator, initialResult: T) { this.state = SchedulerState.IDLE; this.worker = worker; this.result = initialResult; } performUnitOfWork(data: T) { switch (this.state) { case "IDLE": this.state = SchedulerState.PENDING; this.iterator = this.worker(data); throw Promise.resolve(); case "PENDING": const { value, done } = this.iterator.next(); if (done) { this.result = value; this.state = SchedulerState.DONE; return value; } throw Promise.resolve(); case "DONE": this.state = SchedulerState.IDLE; return this.result; } } } 🤯
  74. DID WE JUST useTransition’ED? 🤔

  75. function resourcefulOperation(value: number) { let newValue = String(value); for (let

    i = 0; i < 1000000; i++) { newValue = `${value} + ${i} = ${value + i}`; } return newValue; } function ResourcefulComponent(props: { value: number }) { const { value } = props; const result = resourcefulOperation(value); return <p>{result}</p>; }
  76. function resourcefulOperation(value: number) { let newValue = String(value); for (let

    i = 0; i < 1000000; i++) { newValue = `${value} + ${i} = ${value + i}`; } return newValue; } function ResourcefulComponent(props: { value: number }) { const [_, startTransition] = useTransition(); const [result, setResult] = useState(""); useEffect(() = > { startTransition(() = > { const newResult = resourcefulOperation(props.value); setResult(newResult); }); }, [props.value]); return <p>{result}</p>; }
  77. None
  78. YES, WE DID 🤓 (USING SOME COROUTINES MAGIC)

  79. ↝ THERE’S NO USE OF WORKERS OR WASM FOR PARALLELISM

    ↝ THERE’S A COOPERATIVE MULTITASKING MODEL ↝ A SINGLE RENDERING THREAD, BUT INTERRUPTIBLE SO THAT RENDERING CAN BE INTERLEAVED WITH OTHER MAIN THREAD TASKS AND OTHER REACT RENDERS
  80. ↓ ORIGINAL RENDER TASK USER INPUT → ↑ HIGHER PRIORITY

    RENDER TASK ↓ RESUME ORIGINAL RENDER TASK
  81. ↝ AN UPDATE CAN HAPPEN IN THE BACKGROUND, WITHOUT BLOCKING

    ANOTHER IN RESPONSE TO NEW INPUT ↝ THE SCHEDULER SWITCHES TO THE MORE URGENT RENDERING TASK, THEN PICKS THE ORIGINAL TASK UP AFTER THAT HAS FINISHED
  82. ↝ IT YIELDS EXECUTION IS BACK TO THE MAIN THREAD

    EVERY 5MS ↝ IT'S SMALLER THAN A SINGLE FRAME EVEN ON 120FPS DEVICES, SO IT WON'T BLOCK ANIMATIONS ↝ MOST INDIVIDUAL COMPONENTS DON'T TAKE LONGER THAN A SINGLE FRAME TO RENDER ↝ IN PRACTICE, RENDERING IS EFFECTIVELY INTERRUPTIBLE
  83. Coroutines out there INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED

    A TLDR FOR
  84. ↝ ASYNCHRONY IN JAVASCRIPT IS CONTAGIOUS ↝ IF ANY FUNCTION

    IS ASYNC, THEN EVERYTHING THAT CALLS IT MUST ALSO BE ASYNC… ↝ …AND SO ON UNTIL THE ENTIRE PROGRAM IS ASYNCHRONOUS 🤷
  85. ↝ ASYNCHRONY IN JAVASCRIPT ISN’T FREE ↝ EVERY ASYNCHRONOUS FUNCTION

    CALL HAS TO: ↝ ALLOCATE CALLBACKS ↝ STORE THEM SOMEWHERE ↝ AND TAKE A TRIP BACK TO THE EVENT LOOP BEFORE INVOKING THOSE CALLBACKS
  86. None
  87. ↝ ITS API HAS TWO MAIN FUNCTIONS FOR COMPILING SASS

    FILES: ONE SYNC AND ONE ASYNC ↝ THE ASYNC ONE BECAME WIDELY USED IN PRACTICE BECAUSE IT ENABLED ASYNC PLUGINS (E.G. WEBPACK’S SASS-LOADER)
  88. ↝ FOR NODE SASS, THE PERFORMANCE DIFFERENCE WAS NEGLIGIBLE, BECAUSE

    IT WAS BUILT ON C++ ↝ HOWEVER, DART SASS RUNS AS PURE JAVASCRIPT, WHICH MAKES IT SUBJECT TO JAVASCRIPT’S ASYNC RULES
  89. ↝ THE ASYNC VERSION IN DART SASS WAS 2-3X SLOWER

    THAN THE SYNC ONE ↝ THEY STARTED USING NODE-FIBERS TO IMPLEMENT THE ASYNC API USING THE FAST, SYNC, CODE
  90. HTTPS://GITHUB.COM/ LAVERDET/NODE-FIBERS

  91. None
  92. Effect Handlers INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A

    TLDR FOR
  93. ↝ EFFECTS ASK THE CALLING ENVIRONMENT TO HANDLE A PARTICULAR

    TASK ↝ WHEN AN EFFECT IS USED, THE NEAREST EFFECT HANDLER IS CALLED, WHICH ALLOWS YOU TO RUN CODE IN RESPONSE TO THE EFFECT AND RETURN SOME VALUE. 🤯
  94. HTTPS://OVERREACTED.IO/ ALGEBRAIC-EFFECTS-FOR-THE-REST-OF-US

  95. function getName(user) { let name = user.name; if (name ===

    null) { name = perform 'ask_name'; } return name; } const arya = { name: null, friendNames: [] }; const gendry = { name: 'Gendry', friendNames: [] }; try { getName(arya); } handle (effect) { if (effect === 'ask_name') { resume with 'Arya Stark'; } }
  96. function getName(user) { let name = user.name; if (name ===

    null) { name = perform 'ask_name'; } return name; } const arya = { name: null, friendNames: [] }; const gendry = { name: 'Gendry', friendNames: [] }; try { getName(arya); } handle (effect) { if (effect === 'ask_name') { resume with 'Arya Stark'; } }
  97. function getName(user) { let name = user.name; if (name ===

    null) { name = perform 'ask_name'; } return name; } const arya = { name: null, friendNames: [] }; const gendry = { name: 'Gendry', friendNames: [] }; try { getName(arya); } handle (effect) { if (effect === 'ask_name') { resume with 'Arya Stark'; } } / / THROW → PERFORM / / CATCH → HANDLE / / LETS US JUMP BACK TO WHERE WE PERFORMED THE EFFECT
  98. Effect handlers in React INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU

    WANTED A TLDR FOR
  99. 1. LAYOUT ALGORITHM

  100. THE REACT TEAM APPARENTLY SPENT SOME TIME EXPERIMENTING WITH EFFECT-HANDLER

    CONTROL STRUCTURES FOR MANAGING LAYOUT
  101. HTTPS://GITHUB.COM/REACTJS/REACT-FUTURE/BLOB/MASTER/ 04%20-%20LAYOUT/PROTOTYPE/INDEX.JS

  102. 2. CONTEXT API DRAFTS

  103. THEY’VE ALSO REMODELED THE CONTEXT API USING ALGEBRAIC EFFECTS

  104. HTTPS://GITHUB.COM/REACTJS/RFCS/ BLOB/MAIN/TEXT/0002-NEW-VERSION-OF-CONTEXT.MD

  105. 3. SIDE EFFECTS WITHIN A COMPONENT

  106. HTTPS://GITHUB.COM/ REACTJS/REACT-BASIC#ALGEBRAIC-EFFECTS

  107. function ThemeBorderColorRequest() { } function FancyBox(children) { const color =

    raise new ThemeBorderColorRequest(); return { borderWidth: '1px', borderColor: color, children: children }; } function BlueTheme(children) { return try { children(); } catch effect ThemeBorderColorRequest - > [, continuation] { continuation('blue'); } } function App(data) { return BlueTheme( FancyUserList.bind(null, data.users) ); }
  108. function ThemeBorderColorRequest() { } function FancyBox(children) { const color =

    raise new ThemeBorderColorRequest(); return { borderWidth: '1px', borderColor: color, children: children }; } function BlueTheme(children) { return try { children(); } catch effect ThemeBorderColorRequest - > [, continuation] { continuation('blue'); } } function App(data) { return BlueTheme( FancyUserList.bind(null, data.users) ); } / / THROW → RAISE / / CATCH → CATCH EFFECT
  109. 4. SUSPENSE INTERNALS

  110. 🙋✋ QUESTION #2 HAVE YOU EVER BUILT ANY SUSPENSE-READY API?

  111. HTTPS://GITHUB.COM/FACEBOOK/REACT/BLOB/MAIN/ PACKAGES/REACT-CACHE/SRC/REACTCACHEOLD.JS

  112. A COMPONENT IS ABLE TO SUSPEND THE FIBER IT IS

    RUNNING IN BY THROWING A PROMISE, WHICH IS CAUGHT AND HANDLED BY THE FRAMEWORK.
  113. THROW → HANDLE → RESUME PATTERN. A COMPONENT IS ABLE

    TO SUSPEND THE FIBER IT IS RUNNING IN BY THROWING A PROMISE, WHICH IS CAUGHT AND HANDLED BY THE FRAMEWORK.
  114. Conclusions INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

    FOR
  115. 1. REACT FIBER WAS A REWRITE OF REACT FOCUSED ON

    GIVING MORE LOW-LEVEL CONTROL OVER PROGRAM EXECUTION
  116. 1. ↝ FIBERS AS A LOW-LEVEL COOPERATIVE WAY TO MODEL

    EXECUTION ↝ ALGEBRAIC EFFECTS AS A WAY TO HANDLE EFFECTS WHERE THESE AND THEIR BEHAVIOR ARE INDEPENDENT LOW-LEVEL CONTROL OVER PROGRAM EXECUTION
  117. 2. REACT TRIES TO ADDRESS THE LACK OF SOME JAVASCRIPT

    FEATURES/LANGUAGE-LEVEL RESOURCES BY IMPLEMENTING SOME ALTERNATIVE SOLUTIONS TO ACHIEVE SIMILAR BEHAVIORS
  118. 3. UNDERSTANDING THESE INTERNALS AND THEIR RATIONALES HELPS US IMPLEMENT

    OUR OWN ABSTRACTIONS
  119. HTTPS://WWW.YOUTUBE.COM/WATCH? V=ADNJ3FYDEAO

  120. 4. REACT IS NOT REACTIVE, BUT IT FEELS CONCURRENT

  121. None
  122. 5. THE FACT WE'RE DISCUSSING ALL OF THESE TOPICS SHOWS

    THAT REACT ACTS AS A DEMOCRATIC AGENT FOR THIS KIND OF KNOWLEDGE IN THE FRONT-END WORLD
  123. None
  124. THIS IS THE EIGHT-YEARS-AGO-ME GIVING A TALK ABOUT IONIC AT

    AN IOS DEVELOPERS MEETUP TELLING THEM THAT ANGULAR WOULD BE THE FUTURE.
  125. 6. DON’T ALWAYS TRUST ALL OF MY SPECULATIONS/FUTURE PREDICTIONS 🤷

  126. HTTPS://SPEAKERDECK.COM/ YTHECOMBINATOR/REACT-NEXT-2022

  127. Israel Spain India Czech Republic Mexico We’re hiring! Mostly in:

  128. Israel Spain India Czech Republic Mexico We’re hiring!

  129. Israel

  130. None
  131. MATHEUS ALBUQUERQUE THAT’S ALL, FOLKS! THANKS! QUESTIONS?