React Fundamentals
I recently began a new #100DaysOfCode challenge on Twitter to keep track of my progress through Kent C. Dodd's Epic React workshop. This course covers everything from hooks, patterns, performance and testing, which I will break down section by section in upcoming articles. The format of this course is different than anything I've done before, you're given some incomplete or broken code and are provided tips and descriptions to refactor the code into a working syntax. Today we'll focus on the first module, "React Fundamentals".
Intro to Raw React API's
In this exercise, we were tasked with adding in packages using script tags, and then using two newly accessible global variables, React and ReactDOM which allow you to create React elements and render them to the DOM.
<body> | |
<div id="root"></div> | |
<!-- 💣 remove this line | |
<script src="https://unpkg.com/react@17.0.0/umd/react.development.js"></script> | |
<script src="https://unpkg.com/react-dom@17.0.0/umd/react-dom.development.js"></script> | |
💣 remove this line --> | |
<script type="module"> | |
const rootElement = document.getElementById('root') | |
// You're going to re-implement this code using React! | |
// 💣 So go ahead and delete this implementation (or comment it out for now) | |
// These three lines are similar to React.createElement | |
const element = document.createElement('div') | |
element.textContent = 'Hello World' // 💰 in React, you set this with the "children" prop | |
element.className = 'container' // 💰 in React, this is also called the "className" prop | |
// This is similar to ReactDOM.render | |
rootElement.append(element) | |
// 🐨 Please re-implement the regular document.createElement code above | |
// with these React API calls | |
// 💰 The example in the markdown file should be a good hint for you. | |
</script> | |
</body> |
Below you can see how the children and className props were refactored to use React, and the rootElement is now rendered instead of appended.
<body> | |
<div id="root"></div> | |
<script src="https://unpkg.com/react@17.0.0/umd/react.development.js"></script> | |
<script src="https://unpkg.com/react-dom@17.0.0/umd/react-dom.development.js"></script> | |
<script type="module"> | |
const rootElement = document.getElementById('root') | |
const element = React.createElement('div', { | |
className: 'container', | |
children: 'Hello World', | |
}) | |
ReactDOM.render(element, rootElement) | |
</script> | |
</body> |
Using JSX
In order to use JSX, you have to convert it using a code compiler, in this case we're using Babel. Once Babel is added in, we have to update our own script tag to let Babel know we want our code compiled and ran in the browser.
<body> | |
<div id="root"></div> | |
<script src="https://unpkg.com/react@17.0.0/umd/react.development.js"></script> | |
<script src="https://unpkg.com/react-dom@17.0.0/umd/react-dom.development.js"></script> | |
<!-- 💣 remove this line | |
<script src="https://unpkg.com/@babel/standalone@7.12.4/babel.js"></script> | |
💣 remove this line --> | |
<script type="module"> | |
// 🐨 on the script tag above, change `type="module"` | |
// to `type="text/babel"` so babel will compile this code for the browser to run. | |
// 🐨 re-implement this using JSX! | |
const element = React.createElement('div', { | |
className: 'container', | |
children: 'Hello World', | |
}) | |
// 💰 there are a few subtle differences between JSX and HTML. One such | |
// difference is how you apply a class to an element in JSX is by using | |
// `className` rather than `class`! | |
// 📜 You can learn the differences between JSX and HTML syntax from the React docs here: | |
// https://reactjs.org/docs/dom-elements.html#differences-in-attributes | |
ReactDOM.render(element, document.getElementById('root')) | |
</script> | |
</body> |
After enabling Babel, we're able to use a simpler syntax to create our Hello World element.
<body> | |
<div id="root"></div> | |
<script src="https://unpkg.com/react@17.0.0/umd/react.development.js"></script> | |
<script src="https://unpkg.com/react-dom@17.0.0/umd/react-dom.development.js"></script> | |
<script src="https://unpkg.com/@babel/standalone@7.12.4/babel.js"></script> | |
<script type="text/babel"> | |
const element = <div className="container">Hello World</div> | |
ReactDOM.render(element, document.getElementById('root')) | |
</script> | |
</body> |
Forms
Our objective here was to successfully create an alert showing the users input. By creating a submit event handler, and accepting the 'event' as the argument and the call, we can prevent the default behavior of the form submit. Instead of refreshing, the users input will show in an alert.
import * as React from 'react' | |
function UsernameForm({onSubmitUsername}) { | |
// 🐨 add a submit event handler here (`handleSubmit`). | |
// 💰 Make sure to accept the `event` as an argument and call | |
// `event.preventDefault()` to prevent the default behavior of form submit | |
// events (which refreshes the page). | |
// | |
// 🐨 get the value from the username input (using whichever method | |
// you prefer from the options mentioned in the instructions) | |
// 💰 For example: event.target.elements[0].value | |
// 🐨 Call `onSubmitUsername` with the value of the input | |
// 🐨 add the onSubmit handler to the <form> below | |
// 🐨 make sure to associate the label to the input. | |
// to do so, set the value of 'htmlFor' prop of the label to the id of input | |
return ( | |
<form> | |
<div> | |
<label>Username:</label> | |
<input type="text" /> | |
</div> | |
<button type="submit">Submit</button> | |
</form> | |
) | |
} | |
function App() { | |
const onSubmitUsername = username => alert(`You entered: ${username}`) | |
return <UsernameForm onSubmitUsername={onSubmitUsername} /> | |
} | |
export default App |
There are a few different ways to get the value of an input; via their index: 'event.target.elements[0].value', or via the elements object by their name or id attribute: 'event.target.elements.usernameInput.value'. Let's go with the second option since it's a little more specific.
import * as React from 'react' | |
function UsernameForm({onSubmitUsername}) { | |
function handleSubmit(event) { | |
event.preventDefault() | |
onSubmitUsername(event.target.elements.usernameInput.value) | |
} | |
return ( | |
<form onSubmit={handleSubmit}> | |
<div> | |
<label htmlFor="usernameInput">Username:</label> | |
<input id="usernameInput" type="text" /> | |
</div> | |
<button type="submit">Submit</button> | |
</form> | |
) | |
} | |
function App() { | |
const onSubmitUsername = username => alert(`You entered: ${username}`) | |
return <UsernameForm onSubmitUsername={onSubmitUsername} /> | |
} | |
export default App |
Conclusion
These are only a select few exercises from the first segment of the course, there are quite a bit more, including some extra credit assignments. If you're interested in learning React but aren't sure if you have the prerequisites, I'd recommend taking a look at this article that tells you what JavaScript to Know for React, published by Kent C. Dodds. You can also check out the repository on GitHub for more information.
Give me a follow if you're interested in seeing more articles pertaining to the Epic React course. If you're a student of the course, let me know what your favorite parts were in the comments!
Top comments (0)