React
- Let's create a basic Hello World app using HTML.
<body>
<div id="root">
<div class="container">
Hello World
</div>
</div>
</body>
Let's recreate that using JS
<body>
<div id="root"></div>
<script type="module">
const rootElement = document.getElementById('root')
const element = document.createElement('div')
element.textContent = 'Hello World'
element.className = 'container'
rootElement.append(element)
</script>
</body>
Let's recreate that using JS and a function
<body>
<div id="root"></div>
<script type="module">
const rootElement = document.getElementById('root')
function HelloWorld() {
const element = document.createElement('div')
element.textContent = 'Hello World'
element.className = 'container'
return element
}
rootElement.append(HelloWorld())
</script>
</body>
We can append it multiple times and it will work
- Let's make this a bit more generic, we can call it a Text component.
- provide the text as a parameter
- provide the class as a parameter
<body>
<div id="root"></div>
<script type="module">
const rootElement = document.getElementById('root')
function Text(text, className) {
const element = document.createElement('div')
element.textContent = text
element.className = className
return element
}
rootElement.append(Text('Hello World', 'container'))
rootElement.append(Text('Goodbye World','container'))
</script>
</body>
Let's use object destructuring to make it a bit more readable
<body>
<div id="root"></div>
<script type="module">
const rootElement = document.getElementById('root')
function Text({text, className}) {
const element = document.createElement('div')
element.textContent = text
element.className = className
return element
}
rootElement.append(Text({text: 'Hello World', className: 'container'}))
rootElement.append(Text({text: 'Goodbye World', className: 'container'}))
</script>
</body>
This is all great but, this is not the original intent of JS and it's a bit taxing on the browser to do this. This is where React comes in.
Now what if I want to add children elements to those Text components?
React introduces a new way to create components and manage the DOM.
Let's do the same things with React.
- I'm not setting the app up with a bundler, so I'm going to use the UMD build of React and ReactDOM. (just for demo purposes, you should use a bundler in a real app.)
I'm using unpkg to get the UMD builds of React and ReactDOM.
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@18.1.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18.1.0/umd/react-dom.development.js"></script>
<script type="module">
const rootElement = document.getElementById('root')
const element = React.createElement('div', {
children: `Hello World`,
className: `container`,
})
ReactDOM.createRoot(rootElement).render(element)
</script>
</body>
We can nest components in React
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@18.1.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18.1.0/umd/react-dom.development.js"></script>
<script type="module">
const rootElement = document.getElementById('root')
const element = React.createElement('div', {
className: 'container',
children: [
React.createElement('span', null, 'Hello'),
' ',
React.createElement('span', null, 'World'),
],
})
ReactDOM.createRoot(rootElement).render(element)
</script>
</body>
let's just get rid of the rootElement variable
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@18.1.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18.1.0/umd/react-dom.development.js"></script>
<script type="module">
const element = React.createElement('div', {
className: 'container',
children: [
React.createElement('span', null, 'Hello'),
' ',
React.createElement('span', null, 'World'),
],
})
ReactDOM.createRoot(document.getElementById('root')).render(element)
</script>
</body>
so this is a nice thing that we couldn't easily do with vanilla JS, but honestly it looks tedious and not very readable. React introduces JSX, which is a syntax extension for JavaScript. It looks like HTML, but it's actually JavaScript.
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@18.1.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18.1.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.createRoot(document.getElementById('root')).render(element)
</script>
</body>
Now because this is JS, we can use variables and expressions in our JSX.
Interpolation
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@18.1.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18.1.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 children = 'Hello World'
const className = 'container'
const element = <div className={className}>{children}</div>
ReactDOM.createRoot(document.getElementById('root')).render(element)
</script>
</body>
-
Props
- passing props to a component
- using props in a component
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@18.1.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18.1.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 children = 'Hello World'
const className = 'container'
const props = {children, className}
const element = <div {...props} />
ReactDOM.createRoot(document.getElementById('root')).render(element)
</script>
</body>
Similar to the Text component we created earlier, we can create a component in React.
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@18.1.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18.1.0/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone@7.12.4/babel.js"></script>
<script type="text/babel">
// NOTE: this is NOT being used as a component. We're not quite there yet.
function message({children}) {
return <div className="message">{children}</div>
}
const element = (
<div className="container">
{message({children: 'Hello World'})}
{message({children: 'Goodbye World'})}
</div>
)
ReactDOM.createRoot(document.getElementById('root')).render(element)
</script>
</body>
Using createComponent
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@18.1.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18.1.0/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone@7.12.4/babel.js"></script>
<script type="text/babel">
// This is being used as a component. But it's still not quite awesome yet.
function message({children}) {
return <div className="message">{children}</div>
}
const element = (
<div className="container">
{React.createElement(message, {children: 'Hello World'})}
{React.createElement(message, {children: 'Goodbye World'})}
</div>
)
ReactDOM.createRoot(document.getElementById('root')).render(element)
</script>
</body>
Using JSX
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@18.1.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18.1.0/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone@7.12.4/babel.js"></script>
<script type="text/babel">
// This is being used as a component 🎉
function Message({children}) {
return <div className="message">{children}</div>
}
const element = (
<div className="container">
<Message>Hello World</Message>
<Message>Goodbye World</Message>
</div>
)
ReactDOM.createRoot(document.getElementById('root')).render(element)
</script>
</body>
Let's take a look at how we can style our components.
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@18.1.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18.1.0/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone@7.12.4/babel.js"></script>
<script type="text/babel">
function Message({children}) {
const style = {
color: 'red',
}
return <div style={style}>{children}</div>
}
const element = (
<div>
<Message>Hello World</Message>
<Message>Goodbye World</Message>
</div>
)
ReactDOM.createRoot(document.getElementById('root')).render(element)
</script>
</body>