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)