So what ReactDOM.render
does is you give it a component (in the default CRA arr, it’s called App
) and an element on an HTML page, and it does the work of converting what is defined in the JS to HTML:
function Example() {
return (
<h1>Hello, world!</h1>
)
}
ReactDOM.render(<Example>, document.getElementById('example'))
That would render the component “Example” to the page, in an element with the ID example
. You can have as many render
functions as you want, but generally there will only be one, and that one will render the very top component. React works by having a tree of components, eg
App
Header
Title
Main
Timeline
TimeLineItem
ItemTitle
ItemDescription
TimeLineItem
ItemTitle
ItemDescription
TimeLineItem
ItemTitle
ItemDescription
And the App.js
file would look a little bit like this - note that each React component has a render
function (works basically the same as ReactDOM.render
, but in this case it’s just saying what HTML that particular component should render):
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
title: 'My App',
timelineItems: [
{ title: 'Item 1', description: 'The first item' }
{ title: 'Item 2', description: 'The second item' }
]
};
}
render() {
return (
<div>
<Header title={this.state.title} />
<Timeline timelineItems={this.state.timelineItems} />
</div>
);
}
}
function Header({title}) {
return (
<header>
<h1>{title}</h1>
</header>
);
}
function Timeline({timelineItems}) {
return (
<ul>{ timelineItems.map(TimelineItem) }</ul>
);
}
function TimelineItem({title, description}) {
return (
<li>
<h1>{title}</h1>
<p>{description}</p>
</li>
);
}
So you’re describing App as a div with some children. And those children is described as a header and an unordered list, and that unordered list has some list item children.
And you would just send App
to the render function, it would then take care of rendering all the children underneath it.
CRA puts that rendering function in another file: at the bottom of your file, it says export App
. In the file that has the render
function, it will import App
, then later in the file, ReactDOM.render(<App>, document.getElementById('app'))
.
The reason it does that is just to separate things out - so you write all your code in the App file (and as you go on you write separate files for separate components, then import
them into the app file), and then that main file deals with the rendering. It’s so that each file (each module) just has one job to do, but it’s a bit confusing when you first encounter it.
It’s definitely very very useful to know - once you’re comfortable with it, it makes the initial development much easier, but it does do quite a bit of magic that can make it difficult when you’re just starting out. For example, it’s built on top of a tool called WebPack, which has been configured to watch the files in specific directories - when you make changes and save, it automatically compiles everything. And it’s set up to deal with a lot of things that otherwise you’d have to configure manually - loading CSS, compiling JSX and JS modules, loading SVG images and so on.