React Today and Tomorrow and 90% Cleaner React With Hooks

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

React 16.7 alpha is live. yarn add react@next react-dom@next

Hooks docs: https://reactjs.org/docs/hooks-intro.html

Hooks RFC: https://github.com/reactjs/rfcs/pull/68

Hooks PR: https://github.com/facebook/react/pull/13968

Try hooks in codesandbox: https://codesandbox.io/s/kmm79lzm3v

πŸ‘οΈŽ︎ 15 πŸ‘€οΈŽ︎ u/swyx πŸ“…οΈŽ︎ Oct 26 2018 πŸ—«︎ replies

I'm really glad that this is 1 single video.

πŸ‘οΈŽ︎ 6 πŸ‘€οΈŽ︎ u/sorahn πŸ“…οΈŽ︎ Oct 26 2018 πŸ—«︎ replies

So is everyone just going to put their production apps on react@next now? I'm tempted

πŸ‘οΈŽ︎ 5 πŸ‘€οΈŽ︎ u/themaincop πŸ“…οΈŽ︎ Oct 27 2018 πŸ—«︎ replies

I like the ease of use and composability, I don't like that init code and render code is in the same function which lead to these weird coding constraints (an alternative is possible: https://github.com/reactjs/rfcs/pull/68#issuecomment-433624505).

Another thing to note here is that if they don't bring a compatible API to the class system (and I see no technical reason for not doing so), it's as good as saying classes are deprecated because hooks are a lot more convenient.

πŸ‘οΈŽ︎ 5 πŸ‘€οΈŽ︎ u/guillaume_86 πŸ“…οΈŽ︎ Oct 27 2018 πŸ—«︎ replies

It's so awesome! I released a global state library that utilises hooks and it just made it all so clean and easy. ❀️

https://github.com/ctrlplusb/easy-peasy

πŸ‘οΈŽ︎ 10 πŸ‘€οΈŽ︎ u/controlplusb πŸ“…οΈŽ︎ Oct 27 2018 πŸ—«︎ replies

It looks awesome but I really dislike those ordered-based hooks. It seems to only affect useState however. Why not giving them names?

πŸ‘οΈŽ︎ 4 πŸ‘€οΈŽ︎ u/gpyh πŸ“…οΈŽ︎ Oct 27 2018 πŸ—«︎ replies

I've been working with react for 3 years now. ELI5 react hooks

πŸ‘οΈŽ︎ 2 πŸ‘€οΈŽ︎ u/oli_rain πŸ“…οΈŽ︎ Oct 27 2018 πŸ—«︎ replies

edit: it seems react seems to warn about using useState conditionally, which is somewhat nice

Quick rant: Hooks are super weird.

The two examples below look very similar, but do something completely different, only based on where you put the useState functions.

Works like expected:

import React, { useState, useEffect } from 'react'

export function Counter1() {
  const [useFooOrBar, setUseFooOrBar] = useState(false)
  const [foo, setFoo] = useState(0)
  const [bar, setBar] = useState(0)
  const toggle = () => setUseFooOrBar(!useFooOrBar)

  if (useFooOrBar) {
    const incrementFoo = () => setFoo(f => f + 1)
    return <>
      <h1>Using foo</h1>
      <button onClick={toggle}>Use bar instead</button>
      <button onClick={incrementFoo}>{foo}</button>
    </>
  } else {
    const incrementBar = () => setBar(b => b + 1)
    return <>
      <h1>Using foo</h1>
      <button onClick={toggle}>Use foo instead</button>
      <button onClick={incrementBar}>{bar}</button>
    </>
  }
}

Move useState inwards, boom, completely broken:

import React, {useState, useEffect} from 'react'

export function Counter2() {
  const [useFooOrBar, setUseFooOrBar] = useState(false)
  const toggle = () => setUseFooOrBar(!useFooOrBar)

  if (useFooOrBar) {
    const [foo, setFoo] = useState(0)
    const incrementFoo = () => setFoo(f => f + 1)
    return <>
        <h1>Using foo</h1>
        <button onClick={toggle}>Use bar instead</button>
        <button onClick={incrementFoo}>{foo}</button>
      </>
  } else {
    const [bar, setBar] = useState(0)
    const incrementBar = () => setBar(b => b + 1)
    return <>
      <h1>Using foo</h1>
      <button onClick={toggle}>Use foo instead</button>
      <button onClick={incrementBar}>{bar}</button>
    </>
  }
}

They use global functions to hook into context dependent state almost like the Haskell state monad, but without being explicit in the types or giving any guarantees or predictability. From the one function Counter2 it's relatively clear how to 'fix' the issue. But what if you blindly factor out the Foo and the Bar part out to different functions? Because a lack of proper identity (you don't bind it to a lexical name within your programming language) useState doesn't seem to compose well.

Maybe that's intended? Don't really like it so far.

πŸ‘οΈŽ︎ 3 πŸ‘€οΈŽ︎ u/sfvisser πŸ“…οΈŽ︎ Oct 27 2018 πŸ—«︎ replies

What do they use to present the code with live preview on the side? It looks very slick.

πŸ‘οΈŽ︎ 1 πŸ‘€οΈŽ︎ u/metronome πŸ“…οΈŽ︎ Oct 27 2018 πŸ—«︎ replies
Captions
good morning everyone whoo good morning welcome to react Kampf 2018 my name is Tom Makino I'm the engineering director of the react group at Facebook I'm really excited to be here I'm actually really excited to talk to people from all over the country and actually all over the world and I know joining us on the live stream we have people from all over the place so thank you for being here with us before we get started just a couple of quick logistics if you haven't read the code of conduct yet please do so it's posted by registration it's posted on the website follow it if you have any issues please reach out to me or anyone on the staff the staff is all wearing purple shirts we got a great lineup of talks they're gonna be in this room today and tomorrow but if you need anything else if you need to just get away if you need to make a phone call we have room set up actually directly behind me the breakfast room is available and in the hallway here we're gonna have the fiber arts circle knitting tract with Jen lucre so check that out as well if you want to get away from the talks lastly there's gonna be more updates throughout the day we'll have lunch at noon but before the rest of the the talks here I just wanted to give a big thank you to the organizers putting this on is a lot of work we were a little worried that we weren't gonna be able to put it on this year because it is so much work but we found the organizers of reactor rally ng-conf jameson matt and and joe and then zero slope events really helped us get this put together this year and i'm really really happy that we were able to do it thank you all for being here the first talk is is our keynote talk with Sophie Alpert and Dan Abramov we're all really looking forward to this I'm gonna invite Sophie up first to kick things off for us thanks [Applause] good morning see ya there hello everyone welcome to react calm I'm really excited to be here I'm really excited for the stuff that we have to announce for you this week my name is Sophie Alpert I Sophie bits on the Internet I manage the react core team at Facebook by any better that you use react is doing great our npm downloads are up 70% year-over-year the chrome dev tools extension for react dev tools has been installed by one and a quarter million developers and I can show you this list of companies it's using react although at this point it's so long it's kind of hard to tell how much it changes each year for another point of data we can look at Google Trends which shows web search traffic so it searches for react continue to go up hopefully that means more people are using react not that it's getting more confusing but for a point of comparison we can look at a jQuery which we have just passed for the first time in history but this also shows that we have a lot more room to grow I was procrastinating when I was writing this talk so I was curious to see what else react is more popular than whoops spoiled my joke but react is more popular I found out than renewable energy it's also more popular than orange juice just think about how common orange juice is right and not only that it's more popular than renewable energy and orange juice put together so I think we have a lot to be proud of but but enough about these numbers what I really like to talk about today is our mission would react ever since react was released in 2013 our overarching goal our primary mission has been to make it easier to build great UIs and so when we're adding new features we always try to be very deliberate we want to consider a bunch of things when deciding whether to add a new API if it makes it possible to do something you couldn't do before if it can dramatically simplify the code around react in your components and libraries so that you all have less work to do and users have less code to download that's a win or if it helps encourage best practices like code splitting if we make it easier to code split your app into multiple bundles then our hope is that your apps will end up being faster so that's why we add things like react dot lazy which we announced two days ago you might have seen it but thinking about this mission make it easier to great to build great UIs there are a lot of different ways that we approach this one way we do this is trying to simplify things that are hard if you saw Dayton Dan Abramov stalk from JS conf Iceland then you saw a sneak peek at suspense which is our idea about how to dramatically simplify what's required to do data fetching code splitting and any kind of async data dependencies in your app now another way we try to improve react is by focusing on performance if your app runs faster your users are going to enjoy using it more conversely if your it's laggy if your app is janky then there your users aren't gonna have a great time so we try to spend time on making react itself faster because if react is faster out of the box you all need to spend less time optimizing your own code one recent performance related effort that Dan also talked about in Iceland as what we call time slicing this is going to let you make sure that the most important renders in your app are processed first in order to unblock the main thread and make your apps faster and a third angle that we approach our mission from is developer tooling to help you debug and understand your app from the start react has included developer friendly warnings to help point out problems before you might otherwise notice them and we've had the reactive tools extension which lets you inspect and debug your component trees and in react 16-5 we introduced a new profiler it's a second I don't know what's up with this clicker a second tab their profiler tab that helps you understand what's happening in your app and optimize it so suspense time slicing and the profiler are three of the new features that we've been working on over the last year we're really excited to tell you more about them but that's actually not what I'm here to talk about you're gonna have to wait till Andrew and Brian's talk tomorrow morning to hear about that today I want to take a step back and focus on something else what I like to ask is what in react still sucks and I have three problems that I would like to talk through the first one is reusing logic between multiple components in react our main building block for our applications is a component and components form the foundation of the two main patterns for sharing code in react apps between components which are higher-order components and render props both of these patterns are great for some cases but they also come with a significant downside you need to restructure your app anytime you want to pull one of these in in more complicated examples this leads to what I call wrapper hell most of us have seen component trees that look something like this and the the nesting you end up with makes it difficult to follow the data flow through the app it would be really nice if there was some way to reuse this sort of stateful logic without needing to change the component hierarchy right the second problem I would like to talk about is giant components whose logic is just sort of a tangled mess when you look at a thousand line react component chances are the logic is going to be split across a lot of different lifecycle methods in a way that's pretty difficult to follow let's look at an example let's say we have a class component and in its component did mount method it does a few different things it subscribes to a datastore it sends off a network requests and it starts a timer well if we look at the component we'll unmount method then we're going to see basically the exact three opposite things it needs to unsubscribe from the store it needs to cancel that Network request and it needs to stop the timers and when it comes to implementing component did update the logic tends to get even trickier because you need to compare the old and new props and and and also mirror it again the same tasks that you have in your other lifecycle methods in this example each call here is just one line so this is actually a lot simpler than what you normally see in your components in real-world components you often end up with an even more tangled mess because each each individual task has to be split across different life cycle methods that makes it hard to tell if for instance you forgot to clean up one of the resources when you're unmounting your component it's pretty hard to see that from the code and the third thing that sucks is the class understanding classes in JavaScript can be pretty tricky and today we require you to use class components in order to access state and life cycles if you've ever taken a function component and converted it to a class to add some state you know that there's a fair amount of boilerplate that's required in order to just define a class component most beginners and many experienced devs also tell us that the way binding and this work in classes is pretty confusing it's annoying to have to think about and we also frequently hear that people don't exactly know when to use function components partly because there's always this fear that you're gonna have to convert it to a class later anyway and so you're like should I should I do it now I don't know and so I claim classes are hard for humans but it's not just humans I claim the classes are also hard for machines if you ever looked at a minute ID component file you'll see that all the method names are still unmanned that if you have a method that's completely unused it doesn't get stripped out that's because it's hard to tell at compile time exactly how all the methods fit together we also found that classes make it difficult for us to implement hot reloading reliably and finally when we were prototyping an optimizing compiler to improve the performance of react components we found that classes can encourage some patterns that make it a lot harder for compilers to optimize so here are the three problems that we have we using logic giant components and and classes so reusing logic because you often end up with this wrapper hell giant components because you have the logic split across different life cycles and classes which are difficult for both humans and machines so we think we have a solution that can help with all three of these we're really excited to share it with you to tell you more about it I want to welcome up Dan Abramov [Applause] [Applause] hi my name is Dan I work on the react team and this is my first time in three homes and so Sophie talked about these problems that I think most of you have encountered in react development and of course we could approach these problems one by one so we could try to solve them in isolation but it seems like solving one of them makes some other one worse so for example if we try to solve the rapper hell by putting more logic into components themselves then our components become larger and harder to refactor and then on the other hand if we try to split the components apart into smaller pieces and reuse those then we end up with more nests than in the component tree and we get the rapper hell again and finally in either case we have all the confusion that comes with the classes so we think that this is because these are not three separate problems we think that this is these are three symptoms of one problem and the problem is that react does not provide a simpler smaller lightweight primitive to add state or lifecycle than a class component and so once you add a class component you can split it up further without introducing the rapper helm and in fact it's not a new problem so if you use react for like more than a couple of years you might remember then when react came out it actually included a solution to this problem it was make sense so mix-ins allows you to reuse some methods between classes and this way you wouldn't have all these rappers so should we add mix ends back to react that's right no no we're not gonna do that I mean the codes usually make sense the rounds it's not like it's not broken but we don't encourage using mix-ins and react and if you curious why there is a blog post that we wrote code called mix-ins considered harmful on the react log where we explain that we think in our experience the problems that mix-ins create are worse than the problems that they solve so that's why we don't encourage using mix-ins so perhaps we could just can't solve this problem maybe its inherent to the react component model maybe we should just accept it oh maybe in there is a perhaps there is a different way we could write our components that doesn't suffer from either of these problems and that's what I'm going to talk about today but before I start I want to touch a little bit on the way we approach making changes and additions to react which is a year ago we set up an RFC process so RFC stands for request for comments and it means that whenever we want to make or somebody else wants to make a substantial change or addition to react they need to write up a proposal with detail in the motivation and the detailed design of how this will work and so that's what we're going to do we're excited to announce that we are ready to present a proposal for how we can solve these three problems and importantly this proposal does not have breaking changes or deprecations in it it is strictly additive it is opt-in and it adds some new api's which happens when they try to solve problems and we would love to hear your feedback on this proposal which is why we're we're going to publish it today and we thought about many ways we could share this proposal so maybe we just like right off in there write up an RFC and post it but since we were going to run react Kampf anyway we just decided to to show it here and we're going to demo [Applause] don't worry Damaris the displays sorry technical glitch can somebody who understands projectors help me can I make it mirror my desktop please yeah okay but it doesn't show on the screen I don't see anything that's that's the problem that I had okay disaster averted alright um let me check the font size a little bit you see it fell all right so here is a simple react component that just it is a row this is just some styling and it it renders a person's name and so let's say that we want this name to be editable so how do you do it in react normally well like if we want to add an input there we need to return this component into a class add some local state to it and let that state drive the input so that's exactly what I'm going to do that's what we do today so I'm gonna do the expert default class greeting extense react component and so I'm going to use only stable JavaScript syntax so constructor props super props there is the state going to initialize name to Mary here and I'm going to declare a random method and copy and paste this sorry okay and so I want this to be instead of just rendering the name I want the surrender and input so I'm replacing this by an input and the value of the input is this that state that name and if I make a change I want to call this dot handle name change that's going to be my change color and I'm going to declare it here when the name changes we call says state like we normally do and we set the name to eat at target dot value right so now if I edit the okay so I I need to bind sorry I need to find the events on there okay so now I can actually edit it and it works so a familiar class component is if you work with reactive properly right a lot of those but let's take a step back what if we didn't have to write a class when we wanted to use state so I'm not sure how that's gonna work but I'll just start with what I know I want to render an input so I'm gonna put an input here and the input has a valley and that Valley is the current name so I'll just pass name I don't know where to get name from so it doesn't come from props I'll just declare it and I don't know I'll fill it in later it's gonna have a change down there as well so I'm going to declare unchanged handle name change and I'm adding a function here takes an event and then here I want to tell react to set the name to something but again I'm not sure how to do that from a functional component so I'll just call something called set name with the current input value and I'll just declare it here all right so these two things they're closely related right so one of them is the current value of the name state variable and the other is a function that lets us set the name state variable and so because these things are closely related I'm actually going to put them together as a pair of valleys so I'm going to get them together from somewhere so where do I get them from from react local state so how do I use react local state from a function component well what if I could just use state and past the initial state to specify it let's see if this works yeah it works [Applause] so let's let's compare the two approaches so on the Left we have a familiar class component this state has to be an object we bind some event handlers so that we can access this inside the event handler for this that's a state when we call says state it actually doesn't just set the state that merges the state are the argument into the state object and then when we want to access the state which it is that state and that's something so in the example on the right we don't need to access this that stayed at something because the name state variable is already available in the function it's just the variable and similarly when we need to set the state we don't need to access this that's something because the function that lets has said the name is also available in the scope so what is use state exactly your state is a hook a hook is a function provided by react that lets you hook into react features from your function components and you state is the first hook that we're going to take a look at today but there are a few more so we're going to see them later all right so let's go back to our Familia a class example so let's say we wanted to add a second field for example for a surname so the way we normally do this is we add another key to the state and we I'm going to copy and paste this row it's gonna say surname now it's going to render a surname and handle surname change when I copy and paste this event handler this will be surname and I need to bind it okay MARY POPPINS so we can see that it works so how do we do the same with hooks so one thing we could do is we could make our state an object as you can see that the state with hooks state doesn't have to be an object it can be any primitive we could make it an object if we wanted to but we also don't have to so conceptually surname is is not closely related to state to the name so what we could do is we could declare a second state variable by calling the you state hook again so all declare surname I can give it any name it's just the variable in my code and sets her name callin you state and passing the initial state for that state variable poppins so again government gonna copy and paste the row say username the valet surname handle surname change and when the user edits the surname not sir name we want to set the surname let's see if this works yay it looks like it works so we can see that we can use hooks more than once in a component let's compare the two approaches in more detail so on the Left familiar class component state is always an object has multiple fields McCall says state will merge some something into that object and then when we want to access it we do this that state that something on the right in the example using hooks we use the state hook twice and that declares two state variables name and surname and whenever we call set name or set surname this tells react that it needs to rerender this component just like if we called says state and so the next time reactor renders our components is going to pass the current name and the current surname to our component and then we can use it directly without accessing these that state that something all right so let's go back to our class example what else what other features of reactor we know so another thing you might want to do from a component is to read context so context in case you're not familiar it's like kind of like global variables for a subtree so it's useful for things like read the current theme like visual theme or the current language that the user is using and it's useful to avoid passing everything through props if you need all components to be able to read some value so we're going to import theme context and local context which I already declared in another file and the API you've probably most familiar with for consuming context especially if you have to consume multiple contexts is the render crop API and it looks like this so I'm going to scroll down here so we can choose theme context consumer that gives us the theme in my case it's just going to be a CSS class so I copy this all this code inside the render prop and I'm going to use class name equals theme all right very old-timey and I also want to show the current language so I'm going to use local context consumer and it's going to render another role so I will copy and paste this role can say language language and render it here okay we can see that context works and that's probably normally consume context we actually added a more convenient API for accessing it even classes in 1606 but this is how you can see multiple contexts so let's look at the at how we could do this with hooks so as we said that state is a fundamental feature of react and this is why you can use state and so if we want to use context I need to import my contexts so this is gonna be a themed context local context and now if I want to use context from my component I can use context and then to get the current theme I can use context same context and to get the current locale I can use context local context and this doesn't just read the context it also subscribes the component to updates to this context but it just gives me the current values so I can I can put it into my CSS class name and I can add the bro first language and I can put it here [Applause] all right so let's let's compare the two approaches so this is the traditional kind of render prop API it is very explicit about what it's doing but it does get a little bit nested and you encounter this not just with context with with any kind of render properly API so with hooks it does the same thing but it's flat so we just say we use this context in this context and we get the theme and locale and then we can use them so you might be wondering at this point how can react possibly know for example I have this to you state calls so how does it know which state variable corresponds to which you state call and the answer is that react relies on the order of these calls this may be a little bit unusual and in order for this to work correctly there is a rule that you need to follow when you use cooks and the rule is that you cannot call hook inside a condition it has to be at the top level of your component so if I do something like if props condition and then I call the you state hook here we actually have a linter plugin that is going to complain that this is not the correct way to use hooks and we realize that this is an unusual limitation but it is pretty important for hooks tour correctly and also to enable certain things that I think will you will like that our so a bit later all right so let's go back to our class so the other thing you might want to reach for the class for is lifecycle methods so the most commonly use case for lifecycle methods is you want to perform some side effect such as firing off request performing some kind of imperative Dom mutation interfacing with the browser api's so you might want to do something like this and you can't do during rendering because it's it's not rendered yet so the way you do side-effects and react is you declare a life cycle method like component amount and then let's say that if let me show this so you see at the top of the screen it says react up so there is actually a browser API that lets us update this so let's say we want the tab title to be the name of the person and changed it as I type and so to set it initially I'm going there is a browser you got to do this is documented title equals this that state that name was space was this the state that's her name so now we can see it's as Mary Poppins but then if I if I edit it it doesn't get automatically updated because I also need to implement component it update for the for the side effects to be consistent with what I rendered so I'm going to declare a component it update and just copy and paste this all right so now says Mary Poppins but if I started editing it the document title updates and this is how we perform side effects in a class so how do we do this with hooks well the ability to perform side effects is another core feature of react components so if we want to use an effect from our component make an import use effect from react and then we want to tell react what to do after react has flushed our components to the Dom so we pass a function which is where we perform our effect so I'm going to say document the title equals name plus space plus surname you can see it says Mary Poppins here and if I start editing it actually updates so what default use effect runs both after the initial render and after every update so by default it is consistent with what he rendered and you can opt out of this behavior if like for performance reasons and/or if you have special logic and reinstall after me will touch a little bit on this so let's compare DG approaches so in the in the class we divide method we divide the logic based on lifecycle method names so this is why we have component amount component it update they fire at different times and we sometimes repeat some logic between them we could extract it to a function but still we would have to call it in two places and remember to keep it consistent and with with the effect hook the effects are consistent by default although there is a way to opt out of that and not is that in the class we need to access this that state so there needs to be a special API to do this but in the effect example we actually don't need a special API to access the state variable because it's already in the scope of the function it is declared right above and this is why the effect is declared inside the component rather than the rather than outside because this gives us access to state variables ability to set them and anything else like the current context value for example or any of these contexts all right so let's go back to the familiar class example another thing you might want to use life cycle methods for in a class is subscriptions so maybe you want to subscribe to some kind of browser API and it gives you some value for example the window size and you want to update the state in response to changes to this value and so the way we could do this in a class let's say that we want to that we want to monitor the window width so I'm going to put with interstate this window in there with browser API and I want to render it let me copy and paste this so this is gonna say width and I'm going to render it here it is that state that width this is the width of the window not with of Mary Poppins and I'm going to add a I'm going to add in event listener so we need to actually listen to changes in the width so at window that event add event listener I'll I'm going to listen to the resize event handle resize and I need to declare this event and so this is where we're going to update the with state to be window that inner width and we need to bind it and and I also need to unsubscribe so I don't want a memory leak with like keeping these subscriptions I want to unsubscribe from this event so the way we do this in a class is we create another life cycle method called component will unmount and I'm going to copy and paste this logic here except this will be a remove event listener so we set up in the event listener and we remove the event listener and we can verify that this actually works by dragging this you see the width is changing so it works so let's see how could how we could do this with hooks so conceptually listening to the window width has nothing to do with setting the document title so that's why we're not gonna put it in that effect it's conceptually completely separate effect and just like we could use state more than once to declare multiple state variables we can use effect more than once to perform different side effects so I want to subscribe to window add event listener resize handle resize and I'm gonna need to keep some state for the current width so I'm actually going to declare another state variable so I'll say with and sat with we get them by using state with window inner with as the initial valium and now in my handle resize function I'll just declare it here because it isn't used anywhere else and it's going to set with tree to the current with I mean I need to render it so I'll copy and paste this row I'm gonna say width and finally I need to clean up after this effect so I need to specify how to clean up and again conceptually cleaning up is part of this effect so this effect has a cleaner place and the order you the way you can specify it is that any effect can optionally return a function and if it does return the function then react will call this function to clean up after the effect so this is where we unsubscribe okay let's just verify that this actually works yay so let's compare the two approaches on the Left we have a familiar class component nothing surprising there we we have some side effects some related logic is split apart so we can see that document title has been set here but it's also being set here and then we subscribe to an effect here sorry subscribe to the event here but we unsubscribe here so these things need to be in sync with each other and then this method contains two unrelated methods two unrelated lines so that me in the in feature make it a bit difficult to test them in isolation but it looks very familiar so that's this nice so this code probably looks less familiar but let's take another look at what's going on here in with hooks we separate code not based on the life cycle method name but based on what the code is doing so we can see that there is one effect which is we updated document title that's one thing this component can do and then there is another effect which is subscribing tree to the window resize event and update in the state when it changes and this effect has a cleanup phase which means that when it's time to remove this effect react removes it and avoids the memory leaks and if you've been carefully watching you might notice that since effect run after every render we're just gonna keep resub scribing so there is a way to optimize this so default is to be consistent which is important if you for example use some prop here I need to resupply tea from props or something similar but there is a way to optimize it and opt out of this behavior and Brian in the stock will mention how to do it alright so there is one more thing that I want to show here so this component is getting pretty large and it's fine so we expect that since you now can do more in function components they will get larger and that's totally okay but you might want to reuse some of that logic in other components or extract it or test it separately what's interesting though is that hope calls they are just function calls and components they are just functions so how do you share your logic between two functions you extract it to a different function that's what I'm going to do you're going to copy and paste this and I'm going to create a new function called use window with and I'll just paste it here and so we need the width in our component in order to render it so I need to return it from this function which is the current width and then I can go back up and I can say Const width equals use window width [Applause] [Music] so what is this function we didn't do anything special we just extracted the function but there is a convention here so we are calling this function a custom hook and by convention custom hook names always start with use and so there are two reasons for this we're now going to like read your function name or to string it or anything like this but it is an important convention because first of all this lets us lint automatically for violation of the first rule that I described about : hooks unconditionally so if we didn't know if something is a hook then we wouldn't be able to do that and another reason is that if you just look at the component code you kind of want to know if some function can have some state inside of it so it's important that there is a convention is he okay use something it means that it's potentially stateful and here with gives us the current bits and subscribes us to updates through it so if we wanted to we could even go further it's probably not necessary in this example but I just want to give you like a sense of water you could do so let's say like maybe setting the document title was a bit more complicated and you wanted to like extract it or test it separately so I could just copy and paste this and I could write a new custom hook I'm gonna call this one use document title and so the name and surname don't really make sense in the Scopes context we just want to call this title and this is going to be an argument so custom hooks are JavaScript functions so they can take arguments and return values or not return so it is going to take title as an argument and now in my component I can say use document title name plus surname in fact I could go even further so in this case it's totally unnecessary but again maybe our inputs were more complicated maybe we were tracking whether the input was focused and blurred whether it has been validated submitted and so on so maybe we had some more logic there we wanted to pull it out of our components and reduce duplication and there is already some duplication so we have this like almost identical event handlers so what if we could just I'm going to delete one of them and extract the other one I'm going to create a new hook that I'm going to call use form input so this is my change handler now I'll also copy and paste this declaration so this defines the state for this input and so it's no longer name and set name I'll just color generically Valley and set value it's going to take the initial value as an argument and this is just going to be a handle change and this will set value so what do we want to get in order to use this user input and our component we want to get the current value and a change candor these are the things that we attach to the input so let's just return them return value and unchanged handle change so now if we go back up we can say name equals use form input meri the name is going to be an object with valley and non change fields and surname is use form input Poppins so this is now going to be named at Valley and surnamed at Valley because this is where the string is and so now I can remove this and I can spread over the name object someone is laughing alright let's just verify it and break it yeah it works so each time we poll a hook its state is completely isolated and this is because we just rely on the order of who calls and not on names or anything so you can call the same hook multiple times each call will get its own local state so let's compare the three approaches for the last time so on the Left we have a familiar class component it has some some state in an object bind some methods has some logic spread across different life cycle methods it has a bunch of event handlers uses uses something things from the context and render stuff pretty familiar and on the right pane this may not look like the react components were used to but it kind of makes sense even if you don't know how these functions are implemented you can see okay it uses to form inputs uses some context to get theme and locale it uses the window width and document title and it renders a bunch of stuff and if we want to we can scroll further and we can see okay so this is how the input works this is how setting the document title works this is how the window with suppression works or maybe this could be an NPM package and you don't actually need to know that all we could pull it back into a component or copy and paste between components so hooks give you custom hooks give you the flexibility to create your own abstractions that are not they do not inflate your react componentry and avoid the wrapper hell [Applause] [Music] [Applause] and importantly these are not two separate applications so this is actually one application so I have this window open just to demonstrate that classes can work side by side with hooks and while hooks represent our vision for the future of react we don't want to make breaking changes like this so we need to keep classes working let's go back to you the slides all right now this is a slider you can actually tweet we present the Hookes proposal to you today Hookes led to use all react features without having to write a class they do not deprecated classes but you have the option to not have to write them we intend to cover all use cases for classes with hooks as soon as possible there are a few that are missing but we're working on them and hooks lets you reuse stateful logic extracted out of components tested separately reuse it between different components without introducing the wrapper hell and again importantly it's not a breaking change completely backwards compatible strictly addition additive and you can find the we wrote the documentation for hooks so you can find it at this year around and we want to hear from you the react immune to you when I hear what you think about hooks whether you like them or not and we realize that it's pretty hard to give feedback without actually trying them so we built them and we released sixty sixty and seven alpha it's not a major release it's a minor release but in alpha where you can try hooks and we've been trying them in production at Facebook for about a month so we don't expect major bugs there but the api's themselves may change together with your feedback and I asked you not to rewrite anything like not to rewrite their whole apps and hooks because first of all it's it's a proposal and second because personally I I find that it takes a bit of a mind shift to start thinking in hooks and it might be a bit confusing if you try to just take a class component and convert it but I do encourage you to try using hooks in some of the newer code that you write in and let us know what you think so thank you [Music] [Applause] so in our view hooks represent our vision for the future of reactive but I think they also represent the way we move react forward and that is we don't do big rewrite we want the new patterns that we like better to coexist with the old patterns so that we can have gradual migration and adoption just like you can gradually adopt react itself and this is almost the end of my talk I want to end it on a personal note so I started learning react about four years ago and one of my first questions was why JSX but my second one of the next questions was I can figure out what does the logo have to do with react so the project is not called Adam it's not a physics engine so one interpretation is that it's kind of upon on reactions so atoms participate in chemical reactions reactions react but it's not a flame with react actually Gotti I found a different interpretation that made more sense to me and the way I think about it we know that physical matter consists of atoms and we've learned that it's the types of these atoms and their properties that determine how the physical matter looks and behaves and react has taught me something similar that you can take a user interface and you can split it into these independent units called components and it's the types and properties of these components that can describe how the user interface looks and behaves what's ironic though is that the word Adam it literally means indivisible so when scientists just discovered Adam for the first time they thought this is the smallest thing we're gonna find but later they discovered an electron which is a smaller particle inside the atom and it turned out it actually electrons explain a lot about how atoms work and I kind of feel the same way about hooks I don't feel like hooks are a new feature rather I feel that hooks provide me with access to react features that I already know such as state and context and life cycle and I feel like hooks are a more direct representation of react and that they really explain how a component works inside and I feel like they've been hiding in plain sight for four years and in fact if you look at the react go go you can see those electron orbits there so maybe hooks have been there all along thank you [Music] [Applause] damn thank you so much Sophie thank you as well a couple years ago one of the things we said at the original react Kampf was that we we felt like we found a better model for our the front end of our applications and that the atomic unit it used to be you know you had views and you had models and controllers and we thought that the component was a better kind of primitive for that and I think we're really excited that we hope that hooks will make our applications even more maintainable going forward our next presenter if you use a router in your react application he is almost certainly either partially or completely responsible for that probably needs no further introduction welcome Ryan Florence [Applause] [Music] [Applause] I'm having the same technical difficulties dan did something good company are you feeling a little bit like when you first saw JSX better okay I was I was honestly not quite sure how people were going to respond to it so my talk is 90% cleaner with react hooks I used you might know me from react router I used to work at react training but now I'm running reached at Tech where I'm trying to make react accessible for the developers and their users so I've got open source their workshops online courses and stuff take a look and then also give me a follow on on twitter dan just said don't rewrite your apps in hooks I think you should we're just gonna we're just gonna dig in we're gonna do a bunch of code here and see how hooks feel in a little bit more real-world use case so this is this is kind of this is the state of react today right we got these render props and they get all nested I've loved these things since I saw them at react Europe when Cheng Liu showed us react motion but I have not loved the syntax disaster is what I started calling this render props big trade-off is that syntax disaster Dan and Sophie covered really well a lot of the problems that hooks solve with this so I won't go into any more detail except one other thing is something that's always bothered me about these render props is it gives a false hierarchy here I've got two media listeners where I'm listening to the media query and so I can see if this thing matches that those two queries and it looks like there's a hierarchy here but there's actually not so let's let's see how this code feels when we switch it over to hooks here's how it's all implemented we've got some initial state here we set up when the component mounts we do a quick check here because between initialization or a construction and mounting our screen size could have changed especially with suspense coming so we set some state just in case it changed create a listener add the listener and then we add removed listener to our component instance then we've got a component did update we do a little dip here because if our query changes we want to reset up this listener Reese absque Ribe to it and we need to clean it up as well and then when we unmount we clean it all up and of course we yield out that state or call back with that state with the render prop so let's come to the app and and switch this up instead let's say yeah I'm gonna use let there haven't been enough like semicolon conversations lately so I figured we can start some more of those kinds of conversations and my screen size is kind of small and I'm getting old and typing five characters is you know I'm pushing I'm getting close to 40 I'd rather just type three characters but anyway we're going to use media here let's grab this out drop it in there and then we're gonna have a large same thing use media grab this put it up here I got some extra quotes now and then we just get to delete stuff yeah so many little Woo's out there everyone is pumped about this let's go let's go implement it so let's make use media work so we're going to say function use media and we get the query in as an argument and then up top we're going to have our we're gonna have our state so we're just gonna slide all this code around and see where it moves so our state comes in like this and then we'll say let matches equal use state and we put in that initial state there and of course we need that second part of the return of set matches so that's why our state goes component did mount we just call setup so there's really nothing to do there but we will use an effect here you can think of use effect as component did mount and a few other things but for now just component did now so when we mount we grab all of this stuff and run it so we're going to move all of that into the effect and in here we're no longer reading this dot props like query SEM it's that one as well we're actually just reading an argument that comes into a function it's funny because we've said that about react for a long time right think of props like arguments to a function or what the hooked it is an argument to a function we're not going to read from this state matches we're just gonna read from matches cuz we already got it right up here and then we're not gonna call set state we're going to call actually let's reuse as much code as possible set matches it's important to be efficient no matter what task you're doing don't want to waste CPU cycles up here and we've got our listener we don't call set state let's try that again set matches I practiced last night doing that and then we add the listener and this this not just this but this this is kind of difficult as we've seen you all know that so I don't need to spend any time talking about that so with a hook instead of having to track this this function across our instance we just get to hand that over to react so you know what I don't care when that's supposed to be cleaned up you figure that out okay so now we've got our component did mount in their component did update so this is interesting when we update we dip the prop and see if we should remove the listener and then setup again do we get like previous previous art now where do I do it there's a second argument here the second argument we tell react what stuff matters about this hook so I just tell it well that's almost it i say hey the query matters here some of you were looking at this thinking I liked hooks until now this is the moment no wonder Dan didn't want to cover that part well let Ryan do it he bombed reactor alley so he can all right so this is a whole lot like component did update as well so react is gonna do that diff for us so before you get too grumpy about this API you know and you're probably thinking like oh I don't they passed the arguments back into us don't don't think of it that way don't think of it as these are arguments that I used in here think about a div and if you put will do the innerhtml maybe we did we put the inner or the query as the HTML of the div we don't think about this but react is diffing that query I mean not really it dips the react elements and it does the reconciliation but conceptually we can think react looks at that Korean goes oh that's different now I'm going to go do some Dom node or a Dom node I guess it's the the Twitter egg and we could change the inner HTML to something new right it's gonna go do an effect based on when that query changes so don't don't get too grumpy about this thing we're just we're just letting react do it now I mean we had to dip it anyway and I can't tell you how many bugs there are in my workshops where people forget to diff the prog in component did update and then set things up again so react is now going to handle this diff for us and it will actually remove the listener for us and then it will also set everything back up goodbye component did update all right component will unmount well yeah also if the core you changes will unsubscribe and if the component unmount it'll do that so all that's left is our return and then we return matches let's save it double check our work looks like it works [Applause] 90% cleaner let's see I mean even like I've got prettier set to like 52 columns or something like that and it just it's just kind of like you look at this thing Ike's close your eyes if this makes you dizzy and now it's all just I'm in so cleaned up I don't really like talking about clean code I like code that works I don't usually care how clean it is but I love it when you get an abstraction that actually helps you write code that you don't sort of feel bad about when you deploy it I'm gonna I'm gonna put this back to the to the old way so we'll look at it again later let's look in a little bit more real-world example and what better way to talk about the real world than to look at pictures of the galaxy actually it's not our galaxy these are these are pictures from the Hubble Space Telescope we're gonna build a carousel so I went and did some research on how to build an accessible carousel for people using the mouse screen readers keyboard navigation and all that kind of stuff so we're gonna we're gonna do full-blown carousel here we're not going to do any half stuff or show Mary Poppins window width that's a little creepy if you're tracking that Dan okay so here is here's our app let me bump up the font a bit I've got a current index if I switch this index you'll notice that the slide changes back there we've got some the slide nav is right there here are the slide controls this bar down here is actually a progress bar we're gonna animate this thing that's what we know when the next slide is coming and then when we click these we're also going to manage focus so we're going to move focus from the button that we just clicked to the actual slides so that someone using a screen reader will be able to read the text inside the slide they don't want to just change something and then not read it so let's let's bring this thing to life so we're going to use state here and then we're gonna have our set current index so this is a lot like object D structuring it's kind of new for some people a radies structuring is in some other language that's in Ruby that's where I first learned D structuring but yeah it's just like object destruction but it's arrays and it's actually been around longer than object D structuring and Java is good so let's what should we do let's do the list of the forward and back buttons first so I'm going to come down here to our controls play/pause gonna have a space or gif to have a good app I told you I was old half of you don't know what that is but those that do okay what do we want to do want to say set current index we're going to go backwards so we need to do we're going to do current index minus 1 but we want to cycle through if we get to the first one we're going to do a little bit of computer science here got from stackoverflow don't trust this code you you sometimes like you look at Kodiak that's kind of weird how they did this but I mean Ryan wrote it so I bet he knows what he's doing with it nope so I encourage more comments like that and then down here what do we do we say on click we're gonna set current index here as well but this one's a little bit easier so we're gonna do current index plus 1 and then modulus slice that length so again this is just so that it'll cycle through let's save it come over here cool what should we do next these slideshows usually automatically play right so we're not going to be what I want to do we want to have like an interval or a set timeout or something right but we're going to use effect if we want to put a clock on this page then that's an effect that's something we would have done in component did metal so instead we do it and use effect here and we will set timeout I've got a slide duration already out there and once again we're going to set current index to our new index plus 1 I love computer science so much ok let's save it it's about 3 seconds all right pretty cool play pause let's let's get the let's get the play button working we're getting some more states will say is playing I mean that could work is play 9 and set is playing will use some state we're not playing yet let's come down to our controls here's playing pause so I'll say is playing so if we're playing then let's render the pause button so when we pause we set is playing and then when we play we set is playing to true wait a sec I said false if is playing then set timeout it's important like Dan was talking about you don't do this outside those effects need to be there all the time the way to think about that is you actually really really love hooks in fact you love them unconditionally [Applause] that just that just came to me during Dan's talk and I'm really glad that landed hmm I was actually Jared Palmer told me to get a Captain Hook outfit and like come up here I'd be like I'm gonna show you how to program with hooks and for 30 minutes try to type on my keyboard then we almost went to the strip to go get one but that one might have not been safe for work so we didn't okay so I am I'm gonna save this so it's not playing one two three okay now I'm gonna click the play button one two three cool I'm gonna click the pause button I don't know if I when did i click that so I'm gonna play again okay now I'm gonna pause so I should stop play is is dance still in here I mean I've only been using these for like ten minutes so clear my time out return what all right here we go sorry that was staged I want to see if Dan would actually come up and I know everyone on the react team is like when is he gonna pass the second argument to use effect okay so this this is working right now but it's it's got all sorts of problems this is my favorite one so it's playing and then I click click click click click click then I'll stop I'll get one more and now it's done so we've got to let react know it's got to do that component did update diff and it's got to we need to clear this time out because when I'm when I'm playing and then I hit pause there's that last timeout that's still there that hasn't been cleaned up so that's why we get that one extra in there so what we need to do is a first tell react that uh oh sorry and then the other bug where the click click click happens is I click next next next and the timeout doesn't get cleared and I end up setting multiple timeouts because the current index changes and so I get a re render on every single one so I get a set timeout on every single one of those so I'll come in here and I'll tell it if the current index changes or if is playing changes then I want you to clean up my mess so we'll let our timeout equal that and then we can clear timeout right there so now as that state changes over time react knows when when to clean stuff up so we got one transition I pause it and then it should be done and again don't get grumpy this arguments fine it's just like it's just like this is playing react is already doing dips for you it's already doing that in the reconciler but we're not rendering elements here so this stuff can't participate in that kind of a diff and so when we drop this stuff in here we're saying okay plug this affecting to the Reckling reconciler based on these things just like our just like our elements the owners I emphasize that as I was so grumpy about these okay what's next this progress part let's do the progress bar this thing is really fun so down here we've got a progress bar and we're gonna animate if we're playing so let's go up to the progress bar let's see how it works so we've just got this value here and watch it's gonna bump up to 75% now we can put it back down to 50% and then we could also just use progress and yeah I mean you know you're not sure if you want to clap could you have no idea how it works I think I like it this is not built-in to react this is this is my own custom hood isn't that so cool though it's like I had just a singular value or a static value and to refactor to something stateful is just a function call like it's it's still kind of blowing my mind I haven't gotten bored with react I've been teaching it at workshops for three and a half years thousands of people maybe a hundred workshops and I still don't get bored with it and now there's this stuff and I'm like a little bit hyper when I talk about it and I'll tell you what the last workshops or the last couple weeks have been impossible to keep my mouth shut there are a couple people here who are at some of them and yeah it was I'm like yeah I know a render props are kind of weird hire de components are kind of weird but just wait two weeks I got a survey result back that was like I want my money back everything's changing in two weeks and I was like okay like maybe I should not tell them anything at all it's actually not that great look didn't reset okay so how do we get these these effects to reset we just talked about it's that second argument right so that react can diff and change it so our progress bar down here only knows about time and animate and then our use progress let's go look at it don't worry too much well it's going on here there's just some requestanimationframe and calculating time stamps but it it will reset if anim and time change I don't want to have to tell my progress bar all about current index and is playing if I could pass that stuff in and then it could pass that stuff to use progress then it could pass that to the argument there but react already has a built-in way with our elements to reset state whether you're using hooks or you're using a class component it's the key so you need to say if the current index or is playing changes I want a different instance of a progress bar and then the state inside of the hook I mean it doesn't get reset the thing just goes away and then you get a brand new one but you can think about it as this will reset the state of the progress bar whenever those two pieces of state change cool and now I want to read about the Eagle Nebula hey I want to read the Eagle Nebula pillars are bathed in put hey they ultraviolet light from a grouping of young oh my charge me crazy on websites when like they actually have a carousel that you actually care about and then it just keeps on going so how can we fix that when we click next or previous we could say set is playing false right and then we could do the same thing up here on here set is playing false but the more state we get in these components you kind of end up with with this and that's that's fine but maybe you'd rather do something a little bit more conventional where maybe you've got some state to talk about and maybe you would like to co-locate all of the management of that state with something like I don't know dispatch and to do that maybe you would like to use a reducer this is actually built in to react hooks so it comes comes straight from react we pass it some initial state so the kering index is 0 we pass it is playing faults and then in here I'm just gonna I'm just gonna write the reducer as quick as I can I'm really bad at switch statements though I didn't use them until Redux came around I'm still not sure how I feel about switch statements but uh I can finally write them without having to stackoverflow it so we've got case progress and we've got case next and these these basically do the same thing so I'm going to return all my state and then I'll say is playing if I'm progressing from slide to slide I want to keep playing and so I'll say is playing is action type if I could type it's progress so it'll keep on playing but if I click next it won't be playing anymore and then I'll do the current index yes or computer science almost forgot what to do at the end there and then okay so that's what are we yelling about we're gonna default case alright default turn our state I so got next and progress let's copy this and do previous and oops we're going to subtract from their slides length and then is playing is false and then what else we got we've got case play so when we play I want to say is playing true and then we've got pause and it's playing false one two three four five alright so that is all of them I'm gonna delete this stuff and then we're gonna have some some disasters right here so let's let's fix all of these bugs and what else we got if is playing so what state is playing almost so we're not gonna set current index here we're going to dispatch progress and then down here more putting state on there what else you got yes lint what else you got stay current index we're getting close we don't set his playing we dispatch a tight play and then down here same thing oops this one should be paused I heard somebody grumble over here thank you whenever you hear the grumble looks like you did something wrong but you don't know what they said just just get nervous so previous slide won't do all that anymore we're just dis batch type is a previous same thing here we don't have to do that those two things we just got to say what we're doing go to next a couple more bits here not Sophie bits these are Ryan bits and I got one fan and then this already covered this that's a for the screen reader to know that something's happening okay as a slight happy try not to make you dizzy sliding up here I think it's I think it's happy let's save that yeah throw this stuff on context you can fill in the rest of that statement sorry mark I wrote a blog post called this suspense is killing redux I might write another one called Redux gets the hook but no I I love I love reducers from redux I love thinking about my state on one thing I don't think we talked enough about colocation in the community and we're seeing it now dan talked a whole lot about it where we used to have this kind of stuff spread all over the place in a component but we kind of felt like oh but it's all in a components so it's co-located but we didn't realize that if we looked a little bit closer we had logic spread across our component and that stuff wasn't co-located so hooks led us co-locate these effects colo-colo Kedar state and use reducer it lets us co-locate the changes to the state in this component we're almost done let's uh let's get these things to work and manage some focus so I'm gonna come down to those actually that's what we have a reducer we can actually think about our app and a little bit higher level so we could say which would call this one I'll call it go to because I'm old enough to know that that's a thing but young enough to not know what it really was will have a current index and that will be on action dot index and so then we'll come down to our slide nav here it is and we'll say on click let's dispatch type go to index and use my keyboard now notice the down down here how it's it's highlighted so I'm using my keyboard to navigate around and so what we actually want to do here for a screen reader is and a keyboard user maybe this slide has a form in it or something we actually want to move the focus up to that element and so we'll know that we did it right if this isn't doesn't have that extra circle around it now I got to say here I've been using hooks a little bit longer than the duration of this talk but not much so I'm not sure what the right way to model this focus management is with hooks yet and so don't don't think like oh wow this is cool that's I'm going to do it in my apps I think I think we'll eventually figure out a better way to do it but for now this is this is just kind of the first thing that's come to my mind so I'm gonna have some extra state here and call it take focus and then in each one of these actions I'm going to say take focus faults and then all of them except for go-to and this one I'm going to say true so I want to take focus when we're going to something specifically and then down here words are sliding that are our slides so our slide we can pass in state take focus and now let's go up to our slide sorry a little bit of bouncing around so here's the slide it gets that prop it also knows if it's the current slide we throw Tanner Bendix on there so that we can actually focus it and to focus an element we need a ref hmm so with everything we've seen this morning where do you think we can get a ref from if we need to use a ref how might we use a ref yep and then if we need to focus we use effect and we want to change the focus depending on if we're current and if we should take focus and I'll say if we're current and we should take focus ref current focus notice the circle moves off of there there we go [Applause] [Music] [Applause] ninety percent cleaner react thank you very much [Applause] [Music] [Applause] Ryan thank you so much I like how you snuck in - new - new hooks in there - introduce to everybody we're gonna take a short break about 20 minutes be back in here at 11:00 we'll commence with the the talks but for now I'll have some coffee if you need to use the restroom that's good - thank you
Info
Channel: React Conf
Views: 1,097,455
Rating: undefined out of 5
Keywords:
Id: dpw9EHDh2bM
Channel Id: undefined
Length: 95min 29sec (5729 seconds)
Published: Fri Oct 26 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.