Slide 1

Slide 1 text

Hello, React Next 🙋 🇮🇱 🌎 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR • THE 28TH OF JUNE, 2022.

Slide 2

Slide 2 text

MATHEUS ALBUQUERQUE INSIDE FIBER THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 3

Slide 3 text

I’M MATHEUS 🙋 ↝ @YTHECOMBINATOR ON THE WEB ↝ SR. SOFTWARE ENGINEER @ MEDALLIA ↝ MENTOR @ TECHLABS BERLIN

Slide 4

Slide 4 text

âš  DISCLAIMER âš 

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

2. MAYBE THIS TALK WON’T BE 100% WHAT YOU’D CALL A TLDR 🤯= HUGE CONTENT PAYLOAD / DESERVES FURTHER DISCUSSIONS AFTER THE SESSION

Slide 8

Slide 8 text

A bit of context INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 9

Slide 9 text

HTTPS://GITHUB.COM/ MACABEUS/JS-PROPOSAL-ALGEBRAIC-EFFECTS

Slide 10

Slide 10 text

CONTINUATIONS ALGEBRAIC EFFECTS COROUTINES FIBERS THREADS GENERATORS

Slide 11

Slide 11 text

ALGEBRAIC EFFECTS COROUTINES FIBERS GENERATORS CONTINUATIONS THREADS

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

function add(x,y) { const result = x + y; return result; } add(2, 2)

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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, }, }

Slide 16

Slide 16 text

↝ 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

Slide 17

Slide 17 text

Fibers as Units of Work INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 18

Slide 18 text

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.

Slide 19

Slide 19 text

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.

Slide 20

Slide 20 text

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.

Slide 21

Slide 21 text

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.

Slide 22

Slide 22 text

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.

Slide 23

Slide 23 text

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.

Slide 24

Slide 24 text

Visualizing Units of Work INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 25

Slide 25 text

🤓💻 EXPERIMENT #1 INSPECTING ELEMENTS

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

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; }

Slide 29

Slide 29 text

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; } 🤯

Slide 30

Slide 30 text

No content

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

Manipulating Units of Work INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 34

Slide 34 text

🙋✋ QUESTION #1 HAVE YOU EVER HEARD ABOUT HOMOICONICITY?

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

PERFORMS A TEMPORARY BINDING (BINDS X TO THE VALUE 1) (let [x 1] (inc x)) ; = > 2

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

“…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. 🤯

Slide 40

Slide 40 text

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. 🤯

Slide 41

Slide 41 text

↝ REACT ELEMENTS ARE JUST DATA ↝ JUST LIKE IN LISP, REACT COMPONENTS CAN MANIPULATE THEIR CHILDREN AND RETURN COMPLETELY DIFFERENT THINGS

Slide 42

Slide 42 text

🤓💻 EXPERIMENT #2 PATTERN MATCHING IN REACT

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

/ / . . . export function isWhen( child: ElementWithMetadataUnion ): child is ElementWithMetadata > { return child.element.type === When; } / / . . . export function nodesToElementWithMetadata( children: ReactNode ) { return Children.toArray(children).map((element, idx) = > ({ element: element, position: idx, })) as Array > ; } / / . . .

Slide 45

Slide 45 text

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 ( ); }

Slide 46

Slide 46 text

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 ( ); } PATTERN MATCHING + REACT.SUSPENSE + REACT.LAZY() = USERS DOWNLOAD ONLY THE ACTUAL COMPONENT BUNDLE THAT MATCHES A CONDITION

Slide 47

Slide 47 text

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 ( ); } PATTERN MATCHING + REACT.SUSPENSE + REACT.LAZY() = USERS DOWNLOAD ONLY THE ACTUAL COMPONENT BUNDLE THAT MATCHES A CONDITION MANIPULATING BASED ON ELEMENTS DATA.

Slide 48

Slide 48 text

HTTPS://GITHUB.COM/ YTHECOMBINATOR/REACT-MATCHEZ

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

No content

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

1. A GENERATOR (PRODUCER) THAT CAN ALSO CONSUME VALUES. ↝ JAVASCRIPT GENERATORS CAN CONSUME VALUES ↝ BY THIS DEFINITION, THEY ARE COROUTINES

Slide 53

Slide 53 text

2. A GENERATOR THAT CAN RESOLVE ASYNCHRONOUS VALUES, LIKE ASYNC/AWAIT.

Slide 54

Slide 54 text

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.

Slide 55

Slide 55 text

3. A GENERATOR THAT CAN YIELD WITH A STACKFUL CONTINUATION

Slide 56

Slide 56 text

3. ↝ = DEEP AWAIT ↝ WITH SUSPENSE, WE CAN PAUSE RECONCILIATION AT ANY DEPTH A GENERATOR THAT CAN YIELD WITH A STACKFUL CONTINUATION 🤯

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

Coroutines & React INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 60

Slide 60 text

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.

Slide 61

Slide 61 text

HTTPS://GITHUB.COM/FACEBOOK/REACT/ PULL/6859

Slide 62

Slide 62 text

↝ COROUTINES PER SI IN REACT NO LONGER EXIST. ↝ IT WILL BE FASCINATING TO SEE WHAT FORM COROUTINES TAKE WHEN THEY RETURN TO REACT FIBER.

Slide 63

Slide 63 text

Coroutines & Concurrent React INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 64

Slide 64 text

HTTPS://WWW.YOUTUBE.COM/WATCH? V=NLF0N9SACD4

Slide 65

Slide 65 text

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

{result}

; }

Slide 66

Slide 66 text

No content

Slide 67

Slide 67 text

🤓💻 EXPERIMENT #3 BUILDING A COROUTINES-BASED SCHEDULER

Slide 68

Slide 68 text

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

{result}

; }

Slide 69

Slide 69 text

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

{result}

; }

Slide 70

Slide 70 text

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

{result}

; } / / PROMOTED TO A GENERATOR. / / YIELDING INSIDE AN INFINITE LOOP. / / DOING CONCURRENT STUFF.

Slide 71

Slide 71 text

No content

Slide 72

Slide 72 text

enum SchedulerState { IDLE = "IDLE", PENDING = "PENDING", DONE = "DONE", } class Scheduler { 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; } } } 🤯

Slide 73

Slide 73 text

enum SchedulerState { IDLE = "IDLE", PENDING = "PENDING", DONE = "DONE", } class Scheduler { 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; } } } 🤯

Slide 74

Slide 74 text

DID WE JUST useTransition’ED? 🤔

Slide 75

Slide 75 text

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

{result}

; }

Slide 76

Slide 76 text

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

{result}

; }

Slide 77

Slide 77 text

No content

Slide 78

Slide 78 text

YES, WE DID 🤓 (USING SOME COROUTINES MAGIC)

Slide 79

Slide 79 text

↝ 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

Slide 80

Slide 80 text

↓ ORIGINAL RENDER TASK USER INPUT → ↑ HIGHER PRIORITY RENDER TASK ↓ RESUME ORIGINAL RENDER TASK

Slide 81

Slide 81 text

↝ 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

Slide 82

Slide 82 text

↝ 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

Slide 83

Slide 83 text

Coroutines out there INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 84

Slide 84 text

↝ 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 🤷

Slide 85

Slide 85 text

↝ 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

Slide 86

Slide 86 text

No content

Slide 87

Slide 87 text

↝ 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)

Slide 88

Slide 88 text

↝ 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

Slide 89

Slide 89 text

↝ 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

Slide 90

Slide 90 text

HTTPS://GITHUB.COM/ LAVERDET/NODE-FIBERS

Slide 91

Slide 91 text

No content

Slide 92

Slide 92 text

Effect Handlers INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 93

Slide 93 text

↝ 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. 🤯

Slide 94

Slide 94 text

HTTPS://OVERREACTED.IO/ ALGEBRAIC-EFFECTS-FOR-THE-REST-OF-US

Slide 95

Slide 95 text

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'; } }

Slide 96

Slide 96 text

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'; } }

Slide 97

Slide 97 text

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

Slide 98

Slide 98 text

Effect handlers in React INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 99

Slide 99 text

1. LAYOUT ALGORITHM

Slide 100

Slide 100 text

THE REACT TEAM APPARENTLY SPENT SOME TIME EXPERIMENTING WITH EFFECT-HANDLER CONTROL STRUCTURES FOR MANAGING LAYOUT

Slide 101

Slide 101 text

HTTPS://GITHUB.COM/REACTJS/REACT-FUTURE/BLOB/MASTER/ 04%20-%20LAYOUT/PROTOTYPE/INDEX.JS

Slide 102

Slide 102 text

2. CONTEXT API DRAFTS

Slide 103

Slide 103 text

THEY’VE ALSO REMODELED THE CONTEXT API USING ALGEBRAIC EFFECTS

Slide 104

Slide 104 text

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

Slide 105

Slide 105 text

3. SIDE EFFECTS WITHIN A COMPONENT

Slide 106

Slide 106 text

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

Slide 107

Slide 107 text

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) ); }

Slide 108

Slide 108 text

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

Slide 109

Slide 109 text

4. SUSPENSE INTERNALS

Slide 110

Slide 110 text

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

Slide 111

Slide 111 text

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

Slide 112

Slide 112 text

A COMPONENT IS ABLE TO SUSPEND THE FIBER IT IS RUNNING IN BY THROWING A PROMISE, WHICH IS CAUGHT AND HANDLED BY THE FRAMEWORK.

Slide 113

Slide 113 text

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.

Slide 114

Slide 114 text

Conclusions INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 115

Slide 115 text

1. REACT FIBER WAS A REWRITE OF REACT FOCUSED ON GIVING MORE LOW-LEVEL CONTROL OVER PROGRAM EXECUTION

Slide 116

Slide 116 text

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

Slide 117

Slide 117 text

2. REACT TRIES TO ADDRESS THE LACK OF SOME JAVASCRIPT FEATURES/LANGUAGE-LEVEL RESOURCES BY IMPLEMENTING SOME ALTERNATIVE SOLUTIONS TO ACHIEVE SIMILAR BEHAVIORS

Slide 118

Slide 118 text

3. UNDERSTANDING THESE INTERNALS AND THEIR RATIONALES HELPS US IMPLEMENT OUR OWN ABSTRACTIONS

Slide 119

Slide 119 text

HTTPS://WWW.YOUTUBE.COM/WATCH? V=ADNJ3FYDEAO

Slide 120

Slide 120 text

4. REACT IS NOT REACTIVE, BUT IT FEELS CONCURRENT

Slide 121

Slide 121 text

No content

Slide 122

Slide 122 text

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

Slide 123

Slide 123 text

No content

Slide 124

Slide 124 text

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.

Slide 125

Slide 125 text

6. DON’T ALWAYS TRUST ALL OF MY SPECULATIONS/FUTURE PREDICTIONS 🤷

Slide 126

Slide 126 text

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

Slide 127

Slide 127 text

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

Slide 128

Slide 128 text

Israel Spain India Czech Republic Mexico We’re hiring!

Slide 129

Slide 129 text

Israel

Slide 130

Slide 130 text

No content

Slide 131

Slide 131 text

MATHEUS ALBUQUERQUE THAT’S ALL, FOLKS! THANKS! QUESTIONS?