took down the liveblog from netlify since it was low quality. but it got some bit of traffic.
title: React Conf 2018 Live Blog
description: >-
Come along with us as we learn about the future of React!
authors:
- swyx
date: ‘2018-10-25’
topics: - tutorials
tags: - React
- Live Blog
tweet: >-
Come along with us as we learn about the future of React!
format: blog
—
React Conf starts right now. We will be updating this space with our commentary as the conference happens.
Day 2
Andrew Clark
- Performance is integral to UX
- There is nothing inherently wrong with spinners - on slow networks they show valuable visual feedback
- but if shown unnecessarily, they degrade the UX
- playing count the placeholders
- Concurrent React
- renamed from async to emphasize what makes it special
- work on multiple tasks at a time and switch between them based on priority
- partially render a tree without commiting the result
- does not block the main thread (today react is synchronous)
- designed to solve real-world problems commonly faced by UI developers
- works with hooks and class components!
- Demo
- code splitting with
lazy()
- avoiding spinners with Suspense
- Data fetching with React Cache
- prerendering offscreen content
- code splitting with
- In Suspense, if React starts rendering an async component that isn’t ready yet, it has to render a fallback. The error message is something like
Error: An update was suspended, but no placeholder UI was provided
. - In Sync mode - lazy loading is possible with
.lazy
but it still shows the flash of spinner - In ConcurrentMode - no spinner, no flash
- On a slow network - you need to configure the exact threshold you are willing to wait for before you fallback to a spinner (see Jared’s talk) or else it will delay
- new thing
import {scheduleCallback as defer} from 'scheduler'
- tell React which update to wait longer for
- now: coordinating spinners using suspense
- every component currently has a case where data == null and they individually render a Spinner
- the nice thing about suspense is that you can treat async data over a network as if it were sync data from memory
import {createResource} from 'react-cache' const APIResouce = createResouce(() => fetchAPI()) //reading const read = APIResource.read('reviews/3')
- rely on suspense for fallback
- no local state
- no async event handler
- no classes
- adding
hidden={true}
prop to div - gets the super low offscreen priority prop
Concurrent React summary
- Time Slicing
- rendering is non-blocking, yields to user input
- coordinate multiple updates at different priorities
- preredner content in the background wihtout slowing down visble content on screen
- Suspense
- access async data without blocking
- missed it
Status:
- 16.6: lazy, and Suspense
- 16.7: ConcurrentMode
- ???: React Cache, Scheduler
Profling React - Brian Vaughn
16.5 or newer - you can see profiler in DevTools
features
- record, stop
- at the top it shows each commit. size is determined by render time
- right hand panel shows info about selected commit
- main panel shows info about what the app rendered
- brighter yellow
typeahead usage demo
- Prevent unnecessary renders with
React.memo
- wrap functions in memo - Improve slow renders with
useMemo
:
// rerenders each time
const filteredUsers = filterUsers(users, searchText)
// much faster updates
const filteredUsers = useMemo(
() => filterUsers(users, searchText),
[users, searchText]
)
- label updates with new
trace
API https://fb.me/react-interaction-tracing - new Profiler component in ‘react’ https://fb.me/react-profiling
Moving to Suspense - Jared Palmer
- Incrementally moving to Suspense
- step 0: add Strictmode and address warnings (eg cWM)
- step 1: switch from
ReactDOM.render
toReactDOM.createRoot(domnode).render(jsx)
- step 2: wrap app in
React.Suspense
, add fallback spinner - step 3: swap out any code split component code with
React.lazy
- step 4: use suspense for assets - audio, video, fonts etc. you can show a low quality image placeholder and load the high res version in the background. with suspense, you can let React figure it out.
const ImageResource = unstable_createResouce(source => new Promise(resolve => {
const img = new Image()
img.src = source
img.onload = resolve
}))
const Img = ({ src, alt, ...props }) => {
ImageResource.read(src)
return <img src={src} alt={alt} {...props} />
}
// usage
<React.Suspense fallback={<img
className="artist-image preview"
src={artist.images(2).url}
alt={artist.name}
/>
}
>
<Img
className="artist-image loaded"
src={artist.images(2).url}
alt={artist.name}
/>
</React.Suspense>
use the platform! https://github.com/palmerhq/react-async-elements#the-platform
benefits of suspense
- feels “sync”
- easy to coordinate
- fast and pretty
SVG illustrations as React Components - Elizabet Oliveira
@miuki_miu
Transforming SVG into JSX. Benefits:
- no HTTP requests
- code splitting
- make use of props, state, and event handlers
- disadvantage: complex to update the SVG (design)
https://cassette-tape.now.sh
https://github.com/miukimiu/react-kawaii
The Missing Abstraction of Charting - Chris Trevino
@darthtrevino
- easy to fall off the cliff of abstraction in dataviz - often use 2d APIs instead
- there is a missing abstraction between low level 2d api’s and high level charting api’s
- charting libraries
- victory charts
- react-vis
- recharts
- common issues with these libraries
- victory has taxonomic charts, simple components, and draw primitives
- rechart has taxonomical containers and limited legal children
- react viz has shapes and components but it is the only abstraction level
- they are coupled to a specific rendering tech
- a solution for solving the missing abstraction:
- the Grammar of Graphics
- phases:
- scene specification
- assemble abstract scenegraph
- rendering the graph
- similar to compiler
- program specification
- assemble AST
- assembly
- implemented in python/r with ggplot and altair
- in JS: its
Vega
: https://github.com/vega/vega
- showing sample vega code.
- showing
chart-parts
- a vega alternative with grammar built in? https://github.com/Microsoft/chart-parts- components: provides scales, marks, and guides
- includes a11y!!!!!
AI Conversational Agent Aimed at improving mental health for women - Damini Satya with Elsa
- people dont get help
- women suffer in particular
- need a friend who is a compassionate listener, gives motivation etc
- chatbots today aren’t good
- elsa’s goal
- elsa doesnt help with addictions, not a replacement for therapist
Block the Main Thread - James Long
missed this talk
React Native’s New Architecture - Parashuram N
missed this talk
Let React Speak Your Language - Tomas Erlich
- i18n (languages) vs l10n (cultural)
- having to work with translators who dont code
- example:
{formatDate(now)}
- key is to separate runtime data from language
- normally it uses ICU (International Components for Unicode) MessageFormat
today is {now, date}
: date is a parser- formatting options:
percent
option - pluralization:
{count, plural, one {#book} other {# books}
- this actually looks a lot like jsx!
- variables
- formatting
- built-in
- richtext
- use a babel macro to do this
- transform jsx into icu message format
@lingui/macro
->@lingui/react
- create a RUNTIME catalog
- the biggest problem of i18n in browser: bundle size overhead
- message parser is huge - either runtime parser or compiled messages
- benchmark: 600msgs website, 40% size reduction seen
- future: mozilla is wokring on a new message format projectfluent.org
- Hooks: No
out for the rest of the conference
Day 1
React Today and Tomorrow: Sophie Alpert and Dan Abramov
Note: The Hooks RFC is live here
Fun intro: React is now more popular than jQuery!
What still sucks about React?
- Wrapper hell
- parallel setup/destruct in componentDidMount and componentWillUnmount
- Reusing logic
- classes are confusing (
this
)
Fundamentally: React doesn’t provide a stateful primitive simpler than a class component.
We have a proposal:
- no breaking changes
- Proposed APIs are new
- We need your feedback
Instead of classes and constructors and binding, why not do this:
import { useState } from 'react'
export default function App(props) {
const [name, setName] = useState('Mary')
return (
<div>
<input value={name} onChange={e => setName(e.target.value)} />
</div>
)
}
useState is a hook. We’ll explore more hooks now.
With hooks, state can be a string like we did above, or an object, or we can call the useState
hook twice:
import { useState } from 'react'
export default function App(props) {
const [name, setName] = useState('Mary')
const [surname, setSurName] = useState('Poppins')
return (
<div>
<input value={name} onChange={e => setName(e.target.value)} />
<input value={surname} onChange={e => setSurName(e.target.value)} />
</div>
)
}
ok so that’s the useState hook. notice we dont use classes or this
anymore.
What else do we use classes for?
*useContext
import { useState, useContext } from 'react'
import { ThemeContext } from '../somewhere'
export default function App(props) {
const [name, setName] = useState('Mary')
const theme = useContext(ThemeContext)
return (
<div style={theme}>
<input value={name} onChange={e => setName(e.target.value)} />
</div>
)
}
Unusual Limitation
You cannot call hooks within conditions. it has to be top level. This is an unusual limitation but it enables other things you will see.
Replacing lifecycle methods
To perform side effects in a class we use lifecycle methods. For example, componentDidMount
.
If we want to do it with hooks we do useEffect
:
import { useState, useEffect } from 'react'
export default function App(props) {
const [name, setName] = useState('Mary')
useEffect(() => document.title = name)
return (
<div style={theme}>
<input value={name} onChange={e => setName(e.target.value)} />
</div>
)
}
useEffect
runs both after the initial render and subsequent update.
in classes, we divide logic based on lifecycle method names and have to keep it consistent.
in functions, effects are consistent by default.
tear down
in classes you can tear down whatever you set up in componentDidMount with componentWillUnmount, for example an event listener.
with hooks it is intuitive:
import { useState, useEffect } from 'react'
export default function App(props) {
const [width, setWidth] = useState(window.innerwidth)
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth)
window.addEventLIstener('resize', handleResize)
// cleanup here
return () => {
window.removeEventListener('resize', handleResize)
}
// cleanup above
}
return (
<div>
{width}
</div>
)
}
Effects run after every render, so this adds a lot of listeners. There is a way to optimize this which Ryan will cover later.
One more thing… Custom Hooks!
THIS GUY IS STEVE JOBS REINCARNATE HE EVEN SAID ONE MORE THING
Hook calls are just function calls.. so how do you reuse logic.. you extract it to a different function…
import { useState, useEffect } from 'react'
export default function App(props) {
const width = useWindowWidth()
return (
<div>
{width}
</div>
)
}
// extracted and reusable!
function useWindowWidth() {
const [width, setWidth] = useState(window.innerwidth)
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth)
window.addEventLIstener('resize', handleResize)
// cleanup here
return () => {
window.removeEventListener('resize', handleResize)
}
// cleanup above
}
}
custom hooks must start with “use”. this is an important rule and we will lint for it.
If we wanted to we can even go further. custom hooks are js functions that can take arguments and return whatever values you want.
import { useState, useEffect } from 'react'
export default function App(props) {
const name = useFormInput('Mary')
const surname = useFormInput('Poppins')
return (
<div style={theme}>
<input ...name />
<input ...surname />
</div>
)
}
function useFormInput(initValue) {
const [value, setValue] = useState(initValue)
function handleChange(e) {
setValue(e.target.value)
}
return {value, onChange: handleChange}
}
(WOW!!! wtf)
important: classes can work side by side with hooks although hooks represent their vision for the future of React.
So to sum up: the hooks proposal:
- use all React features without a class
- reuse stateful logic between components
- opt-in and 100% backwards compatible
Docs: https://reactjs.org/hooks
has been in production for a month, api’s may change. dont rewrite your apps with it but try it out and let them know what you think.
It represents the way you move react forward. Dont do rewrites, have new patterns coexisting with old patterns so you can have gradual migration.
On a personal note: What does the atom logo have to do with React? it takes a user interface and splits it into independent units called components. but the irony is that the word atom means “indivisible”, although we later discovered electrons which explain how atoms work. in the same way, doesnt feel like hooks are a new feature. They explain how a component works internally.
if react components are the atoms, hooks are the electrons. They were there all along.
90% Cleaner React - Ryan FLorence
The problem with render props is it gives a false hierarchy.
- render props nested inside each other can look like they have a parent child relationship but really they are siblings
- you can refactor and it goes away!
There is a second argument to useEffect
that tells React what variables to diff. This is like componentDidUpdate
useEffect(() => {
// ...
}, [query])
Refactors class code to hooks, it does look a heck of a lot cleaner.
building an accessible carousel with hooks
too much code to reproduce here
“You actually really really love hooks, in fact you love them unconditionally.”
Demonstrates how to use the second argument in useEffect
together with setTimeout
.
“Writing a custom hook can turn something stateful into a function call.”
- showing off the
useReducer()
hook!!! https://reactjs.org/docs/hooks-reference.html#usereducer
let [state, dispatch] = useReducer(state, action) => {
switch(action.type) {
case 'PROGRESS':
case 'NEXT': return {
...state,
isPlayer: action.type === 'PROGRESS',
}
defafult: return state
}
}
- adding dom nodes with useRef
- combine with useEffect to move the focus to a dom node after render for accessibility!!
Building Todo: the Game in a Cloud-only Environment - Christina Holland
React entirely in the Cloud - developing a react game/app just using a chromebook
Demo: “TODO: the game”
The laptop only has a browser. it has no:
- IDE: AWS Cloud 9
- code files: Github
- packages, cli
- auth, database server: Firebase
- deploy/dev server: now.sh
this is great because you can still work on stuff even if your machine breaks. no “works on my machine” problem.
reasons you might not choose to do cloud-only dev:
- IP/legal concerns
- internet reliability
- pickiness about editors
next demo: Enemies list game
showing how to set up a Firebase/Firestore app, including writing security rules
thought: conf wifi is very important when demoing a cloud-only dev environment…
The Path to a Declaratively Animated Future - Matt Perry aka Popmotion
popmotion vs pose
- imperative vs declarative
- functional vs serialized
- animation-focused vs state-focused
This talk has 3 segments:
- The issues with imperative animation
- a declarative opinionated solution
- ideas for the future
Digression on imperative vs declarative: its a spectrum more than binary choice. how vs what, prescriptive vs descriptive.
The issues with imperative animation
manually constructing transition property, wiring up event listeners, need to interleave animation stuff and scatter around the component.
A declarative opinionated solution: Pose
CSS - is nicely declarative but there are a ton of animation features that it doesnt support eg spring physics
Pose is his attempt at making declarative animation: what if CSS was written with animation in mind first rather than layout or styling
Opinions imposed:
- independent/individual transforms - translations first, then coordinate system. Need
- i missed it
Ideas for the future
Conclusions:
- Imperative api’s are powerful but brittle
- common patterns are an opportunity to simplify things from Imperative -> Declarative -> Opinionated
- Simplifying animation is necessary to keep the web relevant
Lightning talks
- Joe Haddad n Create-react-App v2
- recapping the v2 announcement.
- Post v2:
- typescript support in react-scripts 2.1
npx create-react-app my-app --typescript
- rename app.jsx to app.tsx and install
typescript
- Bryce @brkalow - Components as Units of work
- components have lots of responsibilities - rendering, behavior, styles, side effects, etc
- you can use a
<Refresh />
component to just refresh a page. similar to react-router’s Redirect - Embrace using components beyond presentation
- Marcos Martins @m_u_martins - 5 animations you should know
- hover (using pose) - example on slide
- sticky animation (use styled-components and
position: sticky
) - skeleton loading
- popup/modals?
- didnt catch the last one
- shared components - i had to miss this talk too
- Leta Keane - better living through git hooks
- hooks can: run your tests, standardize commit messages, lint your code, clean up your workflow, etc
- commit lifecycle:
- pre-commit
- automated commit msg
- prepare-commit-msg
- commit msg made
- commit-msg
- post-commit
- does a demo- see her slides for hook examples
GraphQL without GraphQL - Conor Hastings @stillconor
When you want expressiveness of GraphQL queries without a GraphQL backend.
Graphql Design principles
- hierarchy
- product centric
- strong typing
- client specified queries
- introspective
you dont need to have ALL the problems that graphql solves to want to use graphql
solution: RouteQL uses tools from graphql-js and ideas from Apollo to make a system that can talk to any backend.
Launching: https://github.com/conorhastings/routeql
Under the hood:
- uses fetchDedupe to follow a lot of the logic that apollo does to resolve cache queries
Prior art
- “GraphQL Anywhere” - by the apollo team
- Apollo Link Rest
Whats supported?
- Querying
- Mutating
- Polling for data
- Caching of query data (similar options to apollo)
What’s coming?
- making requests from nested selection sets
- moving arguments to more inline with typical queries
- provide automated migration path to apollo
- deferred queries at the top level
- optimistic updates for mutations
- direct access to the cache
Playing with Polyhedra - Nat Alison
polyhedra are awesome
first attempt: d3 + bootstrap + x3dom
second attempt: went better, can render any 3d model
attempt 2.5: made a periodic table of polyhedra
making transform transitions from polyhedra
attempt 3: making transform transitions from for all her polyhedra
- drawing lines between related polyhedra
- transform function to take the table layout and output all the animations
- tried using react-motion - was hard because it was very imperative
- others? anime? gsap? velocity?
making it mobile
- people wont try it out unless you make it mobile usable
- made icons in svg in react
- got rid of horizontal scroll
See: https://polyhedra.tessera.li/
Source: https://github.com/tesseralis/polyhedra-viewer
AR and VR with React Native - Pulkit Kakkar
i missed this talk
React, JS, and WASM to port legacy native apps - Florian Rival
i missed this talk
React for social change
i missed this talk