Course Notes From Kent Dodds Beginners Guide To React Egghead Course

August - 2021

TODO: figure out if you need to combine these or remove one:

/course-notes-from-kent-dodds-beginners-guide-to-react-egghead-course


TODO: Figure out why this isn't working in MDX

NOTE: This started as my notes on the course, but it gets into a critique of the course and my thoughts and ideas for eduction. 

I need to go in and refine some of the examples, but I'm leaving them as is to demonstrate some of the struggles I have with learning from them. 


Beginner's Guide To React from Egghead
======================================

Started on August 7, 2021 - Finished Aug. 15, 2021 (2hr, 35min for reference)

---


At no point in this series do they show you how to make a new react app on your local machine...

They show you how to do it with codesandbox which looks cool, but I want to dev locally so I've got to go figure that out myself. Seems like a huge miss for a beginner course. 

---


You can use this to server HTML files out of a directory:

command
npx browser-sync start --server --files "./*.html" --no-open --no-notify --directory


---


You can call external scripts from [unpkg.com](https://unpkg.com) to use React, Babel, and JSX on a stand alone page that should work even without being on a server 

---


When your doing JSX Stuff, things inside the `{}` are evaluated and the return value is what's rendered

jsx
const message = 'Hello, World'
const className = 'container'
const welcomeElement = <div className={className}>{message}</div>


---


You can use the special `children` property to pass things instead of putting them inside the HTML tags

jsx
const message = 'Hello, World'
const className = 'container'
const welcomeElement = <div className={className} children={message} />


---


If you name your variables `children` and `className`, you can moved them into a `props` variable and use the spread operator to load them like this:

jsx
const children = 'Hello, World'
const className = 'some_style'
const props = { children, className }
const welcomeElement = <div {...props} />


This is because `children` and `className` have special meaning to a react element

---


You can add your own props in from of the `{...props}` spread:

jsx
const children = 'Hello, World'
const className = 'some_style'
const props = { children, className }
const welcomeElement = <div id="myElementId" {...props} />


---


They never say it, but I guessing "props" is short for properties

---


You can also override the props given in `{...props}` by passing a key/value after it:

jsx
const children = 'Hello, World'
const className = 'some_style'
const props = { children, className }
const welcomeElement = <div id="myElementId" {...props} className="a_differnt_style" />


---


One thing they don't mention is if you put `id` in front of `props` but also include an `id` *in* props. Guessing that would overwrite. Will have to check that out. 

---


I don't know the `...` spread operator used in `{...props} and it wasn't explained. Gotta dig into that. Maybe that's something that folks with any recent JavaScript experience know about, but it feels like one of those things that's advanced enough for a beginner's course that it should be explained. (Or, you know, not used at the start?)

---


This is another case of a course showing me 5 ways to do one thing at the start. That burns a huge amount of mental energy with little benefit. Just show me the one I need to go with for now and show me the other ways when I need them. 

And, I don't buy the argument that you need to see all the less efficient ways. All this stuff is abstraction, it's just another level and you can dig into the explanation later after I've got some working code under my belt. 

---


While we're at it, these examples include a style class name without ever using it. I get that they are doing that to help show how you can get to the props, but it's just more mental overhead, especially because it's code on the page that has no effect on the page. 

If you include it, use it. 

---


You can use React Fragments to build things like this:

jsx
const element = (
    <>
        <span>Hello</span>
        <span>World</span>
    </>
)


The lesson starts out by showing it like this: 

jsx
const element = (
    <React.Fragment>
        <span>Hello</span>
        <span>World</span>
    </React.Fragment>
)


This is another case where they could have stuck with one or the other. For example, do the longer, more explit `<React.Fragment>` and don't mention the other one for now. Wait for a few lessons so that folks are used to the idea of a react fragment and used to seeing its name before switching to the shorthand. 

---


There's a decent amount of time spent showing the console of the browser to show what react transforms the source into. This is another case of more information than my beginner brain needs only a few minutes into the course. 

---


You can make a reusable element like this, using the special, built-in `children` property that picks up what's inside the element

jsx
const Message = (props) => <div className="message">{props.children}</div>

const element = (
    <div className="container">
        <Message>Hellllo World</Message>
        <Message>Goodbyeeee World</Message>
    </div>
)


This was an earlier way they showed how to do it (again, frustraing)

jsx
const Message = (props) => <div className="message">{props.msg}</div>

const element = (
    <div className="container">
        <Message msg="Hello Mother" />
        <Message msg="Hello Father" />
    </div>
)


This first time through, they showed it like this. (which is again frustrating since we're not using it)

jsx
const Message = (props) => <div className="message">{props.msg}</div>

const element = (
    <div className="container">
        {Message({msg: 'Hello World'})}
        {Message({msg: 'Goodbye World'})}
    </div>
)


This was another case where they did something one way and then changed it up. The first time through, they used 'message' lower case and then showed the warning it brings and how you need to do it upper case. It would have been better to start with the correct (Uppercase) way and then say something to the effect of "by the way, the reason this is upper case is because..." They also used the `{Message({msg: 'Hello World'})}` format instead of the `` which it sounds like is how everyone actually does it. 

---


This one also spent some time showing type object types in the console. Way more than I need as a beginner and I'm burning a ton of mental energy trying to follow it. 

---


This is how to make a function to work with an element. 

javascript
function Box({className = '', ...rest}) {
    return <div className={`box ${className}`} {...rest} />
}
const element = (
    <Box className="blue" style={{fontStyle: 'italic'}}>
        This is the box
    </Box>
)


- They `className` gets a default value of nothing. Without that, it would error if the `<Box>` didn't have a className. 
- I think the `{...rest}` in the function captures anything that's not already defined, but they didn't make that clear. 
- Apparently, the `{stuff}` inside `function Box({stuff})` is called destructuring, but they don't say what that is. Might be that folks who do JavaScript these days know it, but I never saw it until I came back and am guessing at how it works. 
- The `style` inside the `<Box>` takes an object. Hence the double `{{` and `}}`
- This part `className={`box ${className}`}` renders a 'box' class call for everything and then the `${className}` pulls whatever was passed to the function
- The `className = ''` ensure that if no pathname is passed it default to nothing. 
- This is video 11 which was supposed to be about styling, but all this stuff got thrown in and just kinda breezed past. 

Here's another example from above with some more stuff in it

html
<html>
<head>
    <title>Another Beginner's Guide To React Example</title>  
    <script src="https://unpkg.com/react@16.12.0/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16.12.0/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone@7.8.3/babel.js"></script>
  <style>
    .box {
      border: 1px solid #333;
      display: flex;
      flex-direction: column;
      justify-content: center;
      text-align: center;
    }
    .small {
        width: 80;
        height: 80;
    }
  </style>
</head>
<body>
  <div id="root"></div>
    <script type="text/babel">
        function Box({ className = "", style, ...rest}) {
            return (
                <div 
                className={`box ${className}`} 
                style={{fontSize: 'italic', ...style}} 
                {...rest} 
                />
            )
        }
        const element = (
            <div>
                <Box className="small" style={{backgroundColor:'pink'}}>
                    this is a small box
                </Box>
            </div>
        )
    ReactDOM.render(element, document.getElementById('root'))
  </script>
</body>
</html>


Note that the `{...rest}` doesn't appear to actually get used. And on that note, they show that first instead of the individual props. It's easier to reason about the individual stuff. That should have gone first. 

A `size` prop gets added later which adds even more to the overhead instead of starting over to show things. 

The other thing about this lesson is that they did things in a tricky order, instead of showing you one thing at a time, they introduce a few at a time and then bounce around (e.g. adding the `style` prop, but not using it until later. Also, they could have just done some work on the style prop)

Also did copy paste of the full element which happened fast. it throws a bunch of test on the screen. Would be better to have just done the first element and then introduce difference in a later step (there was just a lot of text on the screen that made it hard to figure out what was going on and rationalize about it)

Part of the point is that you can remove duplication with a function, but that would have been better split out. Or, just do it with one element and then show how you can use it to stamp out a bunch more and walk through the progression that way.

Used multiple cursors at one point to replace a bunch of things at the same time. I don't know how to use multiple cursors. 

---


Thinking about education in general. would be cool to setup something where folks who are new are typing in their own code, but then have something that highlights where there code is different (e.g. missing comma, wrong case)

---


They have prettier or something installed that auto formats the text when they save. In lesson 11, they put a bunch of code on one line and then suddenly it was split across several lines. Originally, it didn't have parens around the return statement but they showed up magically. Much better to turn that off and format manually.

---


Thinking about the "I do it. We do it. You do it." approach. Could make something that does it line by line. Like, have a video that walks through a thing, then a set of videos that does things one line at a time where students can type in their line and it gets checked for accuracy, then let them do it on their own while looking at a sample. 

---


For only being 30 minutes in, there a lot of code that keeps piling on itself. I'd rather the course take longer and split things out more. 

---


Think about adding Anki style spaced repetition to a course

---


Never really explained this syntax

javascript
`${size}`


It's possible that's a well known javascript thing and not a react thing, but I wasn't familiar with it. 

---


Thinking about a course. Don't make folks make decisions, at least not at the start, about what they want to do. Make it opinionated. This is where you going to start and this is the path we're going to take to get you started.

---


The end of lesson 11 went completely off the rails in terms of complexity for a beginner. Throwing all the props into a variable and flipped it to javascript instead of jsx syntax. Like, should I be doing that instead of what you just showed me? If yes? then why did you show me the other stuff. If no, they why are you showing me this? (Yeah, I get it, it's trying to show more details about how things work, but as a beginner, I'm not equipped to understand that and it burns my precious mental energy trying to follow)

---


When you end with "okay, let's put everything back where it was", you've probably left your beginner students in the dust. 

---


There's a 15 second recommendation to tailwind. While nice, it also feels a like a distraction. 

---


As part of the curriculum, talk about ethics, and responsibility

---


Going through lesson 12 , Use Event Hooks With React - 

They start with two functions and state variable already set and then say it's not the way to do rendering or state management...

Would be way better if they should showed a simple hello world style first that updated an element or even jsut wrote to the console. 

doent's talk about how `Object.assing()` works even though that's what we're using. 

---


Anyway, here's a way to call a function from an `onclick` event:

html
<button onClick={() => setState({eventCount: state.eventCount + 1 })}>
    Click me
</button>


---


They make a `handleClick` function that they put inside the `App` function but don't explain why it's there instead of a sibling of the rest of the funcitons

html
function App() {
    function handleClick() {
        setState({eventCount: state.eventCount + 1 })
    }
    return (
        <div>
            ...


---


This is how to get the value of an item that just got updated

html
<input onBlur={event => setState({username: event.target.value })} />


---
 

You can extract the event handler to a function like this:


html
function handleChage(event) {
    setState({username: event.target.value}) 
}

...

<input onBlur={handleChange} />


The author doesn't say way you don't have to pass `event` to the `onBlur` (e.g. why don't you have to do: `<input onBlur={handleChange(event)} />`)

---
 

The author gets into synthetic events vs native events. More info that I don't need right now and burns my mental capacity. 


---


This is the basic way to do state. 

javascript
function Greeting() {

    const [name, setName] = React.useState('')
    const [favoriteColor, setFavoriteColor] = React.useState('')

    const updateName = event => setName(event.target.value)
    const updateFavoriteColor = event => setFavoriteColor(event.target.value)

    return (
        <div>
            <div>
                <form>
                    <label htmlFor="name">Name: </label>
                    <input onChange={updateName} id="name" />
                </form>
                {name ? <strong>Hello {name}</strong> : 'Please type your name'}
            </div>
            <div>
                <form>
                    <label htmlFor="rank">Favorite Color: </label>
                    <input onChange={updateFavoriteColor} id="rank" />
                </form>
                {favoriteColor ? <strong>Favorite Color: {favoriteColor}</strong> : 'Please type your favorite color'}
            </div>
        </div>
    )
}

ReactDOM.render(<Greeting />, document.getElementById('root'))




Do this to set an initial value for `name` of 'carl'

javascript
const [name, setName] = React.useState('carl')


The value gets updated with something like:

javascript
setName('john')


This is what it looks like in a handler with just one item. 

javascript
function Greeting() {
    const [name, setName] = React.useState('carl')
    const handleChange = event => setName(event.target.value)
    return (
        <div>
            <form>
                <label htmlFor="name">Name: </label>
                <input onChange={handleChange} id="name" />
            </form>
            {name ? <strong>Hello {name}</strong> : 'Please type your name'}
        </div>
    )
}


You can add pairs of useState calls:

javascript
const [name, setName] = React.useState('')
const [favoriteColor, setFavoriteColor] = React.useState('')



For the state stuff, this is the first way they showed you how to do it before immediately saying "no one wants to do it like this". Better to use the above, this is just here for reference. 

javascript
function Greeting() {
    const stateArray = React.useState('')
    const name = stateArray[0]
    const setName = stateArray[1]
    const handleChange = event => setName(event.target.value)
    return (
        <div>
            <form>
                <label htmlFor="name">Name: </label>
                <input onChange={handleChange} id="name" />
            </form>
            {name ? <strong>Hello {name}</strong> : 'Please type your name'}
        </div>
    )
}


This example was a little confusing because when I cleared the form box it looked like it went back to the initial default value (which was an empty string), but that's not what was happening. It was getting the empty string from the form via `setName`

---


example would have been better served if they use variables like `name` and `rank` instead of `name` and `name2` in the state video. Also, they used functions called `handleChange` and `handleChange2`. It would have been better to call them `updateName` and `updateRank`

---


Minor thing, but they started with:

html
<div>
    <form />
</div>


and when they added the second example went to:

html
<div>
    <form />
    <div>
        <form />
    </div>
</div>


I almost messed up by copying the full div which would have tried to pass back two elements. Better would have been to start with:

html
<div>
    <div>
        <form />
    </div>
</div>


Which would move to 

html
<div>
    <div>
        <form />
    </div>
    <div>
        <form />
    </div>
</div>


---


The state video has HTML labels on the forms which are generally a good idea but could be eliminated from this for the example so there is less code on the page. 

---


The `useEffect` is called everytime a component gets rendered. If you have something that's using `onchange` to update a state, it'll fire every time the change happens

---


One idea is to have bullet points that you show at the start of each lesson about what the things are. Then, show it once without the student copying along, then once with them. 

---


Another way to do things is to have folks write code in a collapsing way with a checker at each stage to make sure they have it right. That way, they see it before they get errors in the final thing. For example, start by just writing

javascript
function Greeting() {

}


Then

javascript
function Greeting() {
    return (

    )
}


Then

javascript
function Greeting() {
    return (
        <div>
        
        </div>
    )
}


etc...

That will also help show the structure of the code instead of doing it top down, line by line. 

---



NOTE: Don't do this: do the lazy initialize below. (This is a case where it would have been better to show the final thing first and then walk back to this one to show the basics for context. (And, why not to do it. ))

This is the example of how to use `useEffect` to update local storage

javascript
function Greeting() {
    
    const [name, setName] = React.useState(
        window.localStorage.getItem('name') || ''
    )
    
    React.useEffect(() => {
        window.localStorage.setItem('name', name)
    })
    
    const handleChange = event => setName(event.target.value)
    
    return (
        <div>
            <form>
                <label htmlFor="name">Name: </label>
                <input value={name} onChange={handleChange} id="name" />
            </form>
            {name ? <strong>Hello {name}</strong> : 'Please type your name'}
        </div>
    )
}
    
ReactDOM.render(<Greeting />, document.getElementById('root'))


They don't really explian the concept of side effects except to say that it stores data in local storage. Not sure if there's more to it than that. 

---


Lazy usestate initialization

Note that this is the same as above, basically, but a function is used so that the initial value is only called once, even if the component is re-rendered. 

do this:

javascript



instead of this (which is what was above)

javascript
const [name, setName] = React.useState(
    window.localStorage.getItem('name') || ''
)


---


For the react dependency array, they used the empty `<>` as a wrapper. Can't remember if I've seen that here before, but it was distracting. Not sure why they didn't use a `<div>`

javascript
return (
    <>
        <p>stuff</p>
    </>
)


---


When you have an element that contains a `useEffect` and is the child of another element, it will call `useEffect` every time the parent is re-rendered. This can be a performance hit. 

An optimization to prevent this is to pass a "dependency array" as the second argument to use effect (after the function). 

javascript
React.useEffect(
    () => {
        window.localStorage.setItem('name', name)
    },
    [name]
)


With that, the only time useEffect gets called is when `name` has changed. 

Note that it's very important to keep this up to date if you're relying on local stoage, otherwise, what you have live in the app won't get saved. 

The author recommends [eslint-plugin-react-hooks](https://www.npmjs.com/package/eslint-plugin-react-hooks) to help prevent messing up the storage but doesn't got into it enough to tell you how to actually use it. (the rule to use is the exhaustive-depths rule)


---


When it moves to lesson 17, the code base is a pick up for 14 or 15, but stuff is removed from 16. Doesn't really matter, but I copied stuff over so I had to remove it. 

---


Something that might be an interesting idea is to just have a bunch of files that start as shells and then the files that have the progress in different states in the sample repo. For example, the initial template would be:

html
<!DOCTYPE HTML>
<html>
    <head>
        <stuff />
    </head>
    <body>
        <script type="text/babel">
    
    
        </script>
    </body>
</html>


So that folks can start up with just that file. 

Then you could progress with different files showing the state of the progress at different so they can compare directly. And then a final version of it showing the final state. 

---


This is the sample for making a reusable hook

javascript
function useLocalStorageState(key, defaultValue = '') {
    const [state, setState] = React.useState(
        () => window.localStorage.getItem(key) || defaultValue 
    )

    React.useEffect(
        () => {
            window.localStorage.setItem(key, state)
        },
        [key, state]
    )

    // doing this return makes it feel like useState
    return [state, setState]
}

function Greeting() {

    // this is how to now use the new hook instead of 
    // using useState directly. It's now generic
    const [name, setName] = useLocalStorageState('name')

    const handleChange = event => setName(event.target.value)

    return (
        <div>
            <form>
                <label htmlFor="name">Name: </label>
                <input value={name} onChange={handleChange} id="name" />
            </form>
            {name ? <strong>Hello {name}</strong> : 'Please type your name'}
        </div>
    )
}

ReactDOM.render(<Greeting />, document.getElementById('root'))


You don't have to use `use...` as the prefix for your function but if you do some of the linters can do more checking

---
 

They did the thing where they said: 'we could make this a lot more robust by removing the item at the old key if the key is changed, but I'm going to leave that as a fun exercise for you to do later.'

That makes me feel stupid. I have no idea how to do that. 

Can't tell if it's going to be in a later lesson or not. If it is, tell me that now. If not, either don't mention it, or show me how to do it. I'm a beginner, after all.

---
 

It takes way to long to get to the "Watch Again or Watch The Next One" screen. That should be instant. 

Also, when I click "Play Next", it takes me to the page, but doesn't start the video which means I have to click play again. Don't do that, autostart it. (and yeah, I know autostart can be tricky, but it's addressable once a person has interacted with the site)

---


Lesson 18 - Manipulate the DOM with React refs...

I have no idea what's going on in my first watch. I also don't understand what I'm trying to do. They introduced another library and a crapton of custom css. There's a button to hide the content that isn't explained. 

After a few watches, I think I get it. 

- If you want to have something that operates on the DOM object that React renders, use `useEffect` in combination with `useRef`. 
- The `useRef` makes a reference to the node that React creates
- The node won't exist until it's rendered so the `useEffect` is perfect since it gets called when the render happens

This gets into memory leaks and garbage collection because of references to the DOM object. It seems overall like messing with the DOM outside of React is not a beginner level thing. 

---


The lesson numbers in the videos and the sample files are off by one...

---


19 - Understand the React Hook Flow

The video starts off with over 100 lines of code which they blow throw with just mentions of what things do. It's a demo of the flow, but it would be better to put things in piece by piece so I can actually get a sense of where I am in the code and follow along. 

There are a half dozen console log statements showing the flow. They are named "%cApp: something happened". I don't know what the `%c` is. I think it's for a color parameter, but either way it's confusing. It would be better to number the messages and not get fancy with them (e.g. "01 - something happened")

This feels like something it would be good to know, but I can't follow it. If they'd written the code one step at a time, I would have had a chance because I would have understood the parts instead of just being thrown into the giant batch of code that I'm unfamiliar with. 

This must be what it's like for non-technical folks to listen to me and another techie talk about code. 

At 11min 4sec, this is the longest video in the course. At the end of it, they say, "Having a firm understanding of the order on which these things are called is not totally necessary for you to be effective with react."

That's good to know since I couldn't follow it. Makes me wonder if it really needed to be in a beginner course in the first place. 

---


They never explain why some functions are nested and others aren't

---


A good example to show would be the difference between attributes in regular HTML and the props in React. Like, explicitly, so that it really highlights that they are different things even though they look the same. 

---


Make sure things rendered 100% of the time (or you only got one step away from green)

---


For forms, if you set an `id` for the element, you can access it like this (for `id="username"`):

javascript
function handleSubmit(event) {
    event.preventDefault()
    const username = event.target.elements.username.value
    // do something with username
}


Here's the full example:

javascript
function UsernameForm() {
    function handleSubmit(event) {
        event.preventDefault()
        const username = event.target.elements.username.value
        // do something with username
    }

    return (
        <form onSubmit={handleSubmit}>
            <div>
                <label htmlFor="username">Username:</label>
                <input id="username" type="text" />
            </div>
            <button type="submit">Submit</button>
        </form>
    )
}
ReactDOM.render(<UsernameForm/>, document.getElementById('root'))


---


Lesson 20 also shows you how to do `useRef` for forms, but doesn't tell you when or why you'd want to do that. Skipping that for now. Will figure it out if I need it. 

They actually show you a few ways to do it before getting to the one you should use. It would be better to show the right one first and then talk about the other ways that you shouldn't do then circle back to the way to do it. Or, maybe have the ways you shouldn't do it as an optional thing, like in a seperate video? but again, seems like that's not something a beginner needs to keep in mind. just show me the way to do it. If I run into code where someone else did it anther way, I'll figure it out. 

---


Note that `<button>` elements without a `type` are implicitly submit buttons. To make the not that, do:

html
<button type="button">No A Submit</button>


To keep things explicit, set the type for submit too:

html
<button type="submit">Submit</button>


---


Putting `onSubmit={formHandler}` on the `<form>` element catches submits done from buttons or from hitting enter on a text box

---


Use `event.preventDefault()` to keep the page from refreshing when the form is submitted. 

e.g.

html
function handleForm(event) {
    event.preventDefault()
    // do other stuff
}


which will receive `event` from the `onSubmit={formHandler}` call

---



Lesson 21, did a comparison of the username to itself lowercased. Would be better to show how that works outside of the updates for the form handling. Like show it first so I don't have to context switch 

---


You can disable buttons in forms with something like

jsx
<button disabled={Boolean(error)} type="submit">Submit</button>


---


By setting a `value` for a form input, it gets controlled by React. For example, in this case, the input field is changed to lower case when a user types anything uppercase. 

jsx
function UsernameForm() {
    const [username, setUsername] = React.useState('')

    function handleChange(event) {
        setUsername(event.target.value.toLowerCase())
    }

    function handleChange(event) {
        event.preventDefault()
    }

    return (
        <form onSubmit={handleChange}> 
            <div>
                <label htmlFor="username">Username:</label>
                <input id="username" type="text" onChange={handleChange} value={username} />
            </div>
            <button type="submit">Submit</button>
        </form>
    )
}
ReactDOM.render(<UsernameForm/>, document.getElementById('root'))


---


23 using error boundries

---


This is the first time making a class has happened. That should have been its own thing. not tied into error handling. Because it is, I have to learn two things at once. 

---


They show you how to make a class before saying they never make classes and then pointing you to a plugin they use. 

Again, for the beginner, just start with the plugin. Especially if you don't do the class thing yourself as a pro. 

---


The error library used is:

https://www.npmjs.com/package/react-error-boundary

---


24 - Using the key prop when rendering a list with react

---


what the hell. another huge amount of code that they spend just a few seconds explaining before starting to get into the topic. I have no idea what's going on on first viewing. 

---


They show you how to do map to turn into a series of element, but it would be way better to split that out to its own lesson. 

---


The crux of the lesson is when you're using map to make a set of element, you need to add a `key` prop with some unique value to them.

jsx
const animals = [
    { id: 1, name: "cat" },
    { id: 2, name: "dog" },
    { id: 3, name: "fox" },
    { id: 4, name: "monkey" }
]

function TheList() {
    return (
        <ul>
            {animals.map(animal => (
                <li key={animal.id}>{animal.name}</li>
            ))}
        </ul>
    )
}
ReactDOM.render(<TheList/>, document.getElementById('root'))


Note that the video doesn't make it clear how in their example they iterate over the items in the list. You have to trace it through use state. 

---


Lesson 25 - Lifting and Colocating State

---


Pretty sure this is the first time I've seen them use something like `onNameChange` instead of `onChange` in an `<input>` field. If that's the case, they don't explain it. 

---


Also, in the other examples, they would call a function like:

jsx
onChange={functionName}


In this one, they do:

jsx
onChange={event => setName(event.target.value)}


Would have been nice to been given a heads up about the change since that's the first time I've seen it, I think

---


Thing to cover in a beginner course that gets into JS as well is string inside backtics that have variables in them e.g.

jsx
`hello, ${name}`


---


This is the example of how to have state lifted into a parent of two siblings that need to deal with each others state. The `onWhateverChange` is still something I'm getting my head around. I diagram or two probably would have helped. 

jsx
function Name({name, onNameChange}) {
    return (
        <div>
            <label>Name: </label>
            <input value={name} onChange={onNameChange} />
        </div>
    )
}

function FavoriteAnimal({animal, onAnimalChange}) {
    return (
        <div>
            <label>Favorite Animal: </label>
            <input value={animal} onChange={onAnimalChange} />
        </div>
    )
}

function Display({name, animal}) {
    return <div>{`Name: ${name} - Animal: ${animal}`}</div>
}

function App() {
    const [name, setName] = React.useState('')
    const [animal, setAnimal] = React.useState('')
    return (
        <form>
            <Name
                name={name}
                onNameChange={event => setName(event.target.value)}
            />
            <FavoriteAnimal animal={animal} onAnimalChange={event => setAnimal(event.target.value)} />
            <Display name={name} animal={animal} />
        </form>
    )
}

ReactDOM.render(<App/>, document.getElementById('root'))


---


26 - HTTP Requets

---


Another one where there's a lot going on including a big graphQL statement that looks like gibberish to me. 

I type in code when I'm learning and this really discourages that. Plus, not being familiar with graphQL, it's another drain on my headspace. 

There's a form and some updates and some state. I've seen all that stuff, but I'm still struggling to get it. So, it's noise getting in the way. Better to show me the thing in isolation and then combine it back. 

---


`useEffect` gets described as a callback. I believe that's the first time I heard that term in this context. 

---


In the first part of the video, this is the order of the lines that were highlighted and described:

9
10
1
2
5
6
3
4
7
8
11
12


That was hard to follow since I'm not familiar with the lines yet. Would have been different if I typed them, or if they had at least been typed. 

---


In the example returning data from `fetch`, they use:

jsx
.then(r => r.json())
.then(response => response.data.pokemon)

    
That makes it look like they are two different things somehow, but I'm pretty sure they are both responses in which case this would have been better (unless there's some reason I don't know whey not do to it)

jsx
.then(response => response.json())
.then(response => response.data.pokemon)


consistency is key

---


Here's the example I did for myself to figure out what was going on. 

jsx
function App() {
    const [theStatus, setTheStatus] = React.useState('Checking')
    React.useEffect(() => {
        fetchWeatherStatus().then(
            weatherStatusData => {
                setTheStatus(weatherStatusData.status)
            }
        )
    })
    return (
        <div>{`Status: ${theStatus}`}</div>
    )
}

function fetchWeatherStatus() {
    return window.fetch('https://api.weather.gov/')
        .then(response => response.json())
}

ReactDOM.render(<App/>, document.getElementById('root'))


Compare this to the example from the video:

jsx
function PokemonInfo({pokemonName}) {
  const [pokemon, setPokemon] = React.useState(null)

  React.useEffect(() => {
    if (!pokemonName) {
      return
    }
    fetchPokemon(pokemonName).then(pokemonData => {
      setPokemon(pokemonData)
    })
  }, [pokemonName])

  if (!pokemonName) {
    return 'Submit a pokemon'
  }

  if (!pokemon) {
    return '...'
  }

  return <pre>{JSON.stringify(pokemon, null, 2)}</pre>
}

function App() {
  const [pokemonName, setPokemonName] = React.useState('')

  function handleSubmit(event) {
    event.preventDefault()
    setPokemonName(event.target.elements.pokemonName.value)
  }

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <label htmlFor="pokemonName">Pokemon Name</label>
        <div>
          <input id="pokemonName" />
          <button type="submit">Submit</button>
        </div>
      </form>
      <hr />
      <PokemonInfo pokemonName={pokemonName} />
    </div>
  )
}

function fetchPokemon(name) {
  const pokemonQuery = `
    query ($name: String) {
      pokemon(name: $name) {
        id
        number
        name
        attacks {
          special {
            name
            type
            damage
          }
        }
      }
    }
  `

  return window
    .fetch('https://graphql-pokemon.now.sh', {
      // learn more about this API here: https://graphql-pokemon.now.sh/
      method: 'POST',
      headers: {
        'content-type': 'application/json;charset=UTF-8',
      },
      body: JSON.stringify({
        query: pokemonQuery,
        variables: {name},
      }),
    })
    .then(r => r.json())
    .then(response => response.data.pokemon)
}

ReactDOM.render(<App />, document.getElementById('root'))


Mine is 20 lines. Here's another version I put together showing how to use a button to run the update:

jsx
function App() {
    const [theStatus, setTheStatus] = React.useState('???')
    const [pageFetchInProgress, setPageFetchInProgress] = React.useState(false)

    React.useEffect(() => {
        if (pageFetchInProgress) {
            window.fetch('https://api.weather.gov/')
                .then(response => response.json())
                .then(response => setTheStatus(response.status))
            setPageFetchInProgress(false)
        }
    })

    return (
        <div>
            <div>API Status: {theStatus}</div>
            <button onClick={() => setPageFetchInProgress(true)}>Check Status</button>
        </div>
    )
}

ReactDOM.render(<App/>, document.getElementById('root'))


22 lines...

---


The one in the video is good for showing the input fields. I don't have a problem with that. The trick is that it was just hard to get to the first time. Once I made my own trimmed down version, it was easier to follow along. Would love to see it where they started with the more simply examples and then moved up to the more complicated. 

---


27 - HTTP calls with error handling

---


This is what I came up with. It's a little more straight forward for me to understand than the example they give to start with. Their example is nice, but the order they give it in threw me a little and it has a little more stuff in it than needed for. see below

jsx
<!DOCTYPE HTML>
<html>
<head>
    <title>Fetching Remote Data With A Button Click And Error Handling</title>  
    <script src="https://unpkg.com/react@16.12.0/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16.12.0/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone@7.8.3/babel.js"></script>
<style>
body { background-color: #555; }
</style>

</head>
<body>
    <p>Fetching Remote Data With A Button Click</p>
    <p><a href="/">Home</a></p>
    <div id="root"></div>
    <script type="text/babel">
        function App() {
            const [statusMessage, setStatusMessage] = React.useState('TBD')
            const [fetchStatus, setFetchStatus] = React.useState('ready')

            React.useEffect(() => {
                if (fetchStatus === 'pending') {
                    window.fetch('https://api.weather.gov/')
                        .then(response => response.json())
                        .then(
                            response => {
                                setStatusMessage(response.status)
                            },
                            errorData => {
                                setStatusMessage('ERROR')
                            }
                        )
                    setFetchStatus('ready')
                }
            })

            return (
                <div>
                    <div>API Status: {statusMessage}</div>
                    <button onClick={() => setFetchStatus('pending')}>Check Status</button>
                </div>
            )
        }

        ReactDOM.render(<App/>, document.getElementById('root'))
    </script>
</body>
</html>


And here's the example from the course for comparison. 

jsx
<body>
  <div id="root"></div>
  <script src="https://unpkg.com/react@16.12.0/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16.12.0/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/standalone@7.8.3/babel.js"></script>
  <script type="text/babel">
    function PokemonInfo({pokemonName}) {
      const [status, setStatus] = React.useState('idle')
      const [pokemon, setPokemon] = React.useState(null)
      const [error, setError] = React.useState(null)

      React.useEffect(() => {
        if (!pokemonName) {
          return
        }
        setStatus('pending')
        fetchPokemon(pokemonName).then(
          pokemonData => {
            setStatus('resolved')
            setPokemon(pokemonData)
          },
          errorData => {
            setStatus('rejected')
            setError(errorData)
          },
        )
      }, [pokemonName])

      if (status === 'idle') {
        return 'Submit a pokemon'
      }

      if (status === 'rejected') {
        return 'Oh no...'
      }

      if (status === 'pending') {
        return '...'
      }

      if (status === 'resolved') {
        return <pre>{JSON.stringify(pokemon, null, 2)}</pre>
      }
    }

    function App() {
      const [pokemonName, setPokemonName] = React.useState('')

      function handleSubmit(event) {
        event.preventDefault()
        setPokemonName(event.target.elements.pokemonName.value)
      }

      return (
        <div>
          <form onSubmit={handleSubmit}>
            <label htmlFor="pokemonName">Pokemon Name</label>
            <div>
              <input id="pokemonName" />
              <button type="submit">Submit</button>
            </div>
          </form>
          <hr />
          <PokemonInfo pokemonName={pokemonName} />
        </div>
      )
    }

    function fetchPokemon(name) {
      const pokemonQuery = `
        query ($name: String) {
          pokemon(name: $name) {
            id
            number
            name
            attacks {
              special {
                name
                type
                damage
              }
            }
          }
        }
      `

      return window
        .fetch('https://graphql-pokemon.now.sh', {
          // learn more about this API here: https://graphql-pokemon.now.sh/
          method: 'POST',
          headers: {
            'content-type': 'application/json;charset=UTF-8',
          },
          body: JSON.stringify({
            query: pokemonQuery,
            variables: {name},
          }),
        })
        .then(r => r.json())
        .then(response => response.data.pokemon)
    }

    ReactDOM.render(<App />, document.getElementById('root'))
  </script>
</body>


Overall, the course was a little harder for me to understand than what I'd like to see in a beginner course. It went too fast and I had to do a bunch of review. I spent 20+ hours going over the 2.5 hours worth of videos. That's not awful, by the way. It's just that that effort was harder than it had to be based off the way I learn. 

The thing I keep coming back to though is that it didn't show me how to make a local react app for development. The codesandbox example they show is nice and all, but I want to do local dev. So, I'm off to look at create-react-app. 

If you'd like to see the full set of examples from the course they are available in [this github repo](https://github.com/kentcdodds/beginners-guide-to-react)