Recently, I walked through building a basic React App.1 In retrospect, I could make it even more basic by removing any package managers, bundlers, or other tooling.
NB: This exercise is adapted from Brian Holtβs Frontend Masters course (which is also where I borrowed the styling from). Heβs posted all of the course notes on Github too.2
To get started, all we need is an index.html
and a style.css
.
My project looks like this (the src
directory is just for organization):
.
βββ src
βββ index.html
βββ style.css
Want to see an entire React app in one file?
<!DOCTYPE html>
<html lang="βenβ">
<head>
<meta charset="UTF-8" />
<meta name="βviewportβ" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Adopt Me</title>
<link rel=βstylesheetβ href=β./style.cssβ/> // import styles
</head>
<body>
<div id="root">not rendered</div>
<script src="https://unpkg.com/react@16.8.4/umd/react.development.js"></script>
// import react
<script src="https://unpkg.com/react-dom@16.8.4/umd/react-dom.development.js"></script>
// import react-dom to actually mount react
<script>
const App = () =>
React.createElement(
'div', // the element thatβs rendered
{ id: `main-div` }, // the props that are passed to the rendered element
React.createElement('h1', {}, 'Adopt Me!') // the children of our element
) // our current entire app
ReactDOM.render(React.createElement(App), document.getElementById('root'))
</script>
</body>
</html>
VoilΓ‘. We have our app rendering!
So, whatβs actually happening here? Weβre using pure React with the createElement
method featured prominently. In fact, we use it three times:
- To create the
App
component - To create a
div
- To create an
h1
createElement
takes three arguments (the latter two are optional):
- The component to render
- Any props and attributes to pass through to the component
- Any children of the component.
Passing A Sub Component
So far, we donβt have a very interesting application however. How could we extend it?
Letβs start with a child that actually receives props.
<script>
const Header = (props) => {
return React.createElement("h1", {}, "Adopt Me! We have ${props} animal(s) available")
}
const App = () => React.createElement(
"div",
{id: `main-div`},
React.createElement("div", {}, React.createElement(Header, {value: 1}))
)
ReactDOM.render(React.createElement(App), document.getElementById('root'))
</script>
Whatβs interesting here is to see how we simply repeat the pattern, though this time, the composite component, Header
is receiving props (value:1
) which we see in the console.
Multiple Children
Since a div can have multiple children, if we want to pass more than one, just list them in an array.
<script>
const Subheader = (props) => React.createElement(βh1", {}, `We have ${props.value} animal(s) available`)
const App = () => React.createElement(
"div",
{ id: 'main-div' },
React.createElement("div", {},
[
React.createElement("h1", {}, `Adopt Me!`),
React.createElement(SubHeader, { value: 1 })
])
)
ReactDOM.render(React.createElement(App), document.getElementById('root'))
</script>
Extracting React From The HTML
This isnβt very easy to manage, however. Letβs pull these pieces apart so weβre not writing Javascript directly in our HTML.
We can start by adding an App.js
file to the src
directory.
.
βββ package.json
βββ src
βββ App.js
βββ index.html
βββ style.css
Copy the Javascript code (everything in the <script>
tag) to App.js
Update the <script>
tag to reference the App.js
as its source.
<script src="./App.js"></script>
Thatβs it. Weβve now rendered a React App without npm
, without webpack
, and without embedding the Javascript in the HTML.
At this point weβve written a pure React app. No tools. No npm. No bundles. We could keep going like this too. Though, I find the tools helpful. For more on that see my other walkthrough, Getting A Basic React App Up and Running1.
Top comments (0)