React/ReactJS: Components and Props
The line below exist inside the
src/index.js file of the boilerplate
application created by the
create-react-app
command line (CL) tool.
ReactDOM.render(<App/>, document.getElementById('root'));
The first argument <App/> passed
into the ReactDOM.render() function is a
component. They are the fundamental independent blocks of code of a
ReactJS application and we are going to learn about them here.
Note that ReactJS components should always start with a capital letter. Components starting with lowercase letters are treated like any other HTML DOM tags.
We begin by replacing the
<App/> component directly with a
simple JSX
<h1>Hello, World!</h1>.
ReactDOM.render(<h1>Hello, World!</h1>, document.getElementById('root'));
What happens from here, we have described in our previous tutorial "The JSX". The Babel package
transforms this JSX into
React.createElement() function calls as
follows —
React.createElement(
"h1",
null,
"Hello, World!"
);
Note that I wrote "function calls" in plural to imply generically that
if h1 has a child element, another
React.createElement() would appear nested.
You can try out your JSXes in Babel's online compiler
here and see how
they are converted.
JSX transformation in Babel
The React.createElement() function in turn
creates an object — a JavaScript object — known as
React Element. We can check what this object is like by doing
console.log() of what the Babel compiler
returned.
console.log(React.createElement("h1", null, "Hello, World!"));
{
key: null,
props: {
children: "Hello, World!"
},
ref: null,
type: "h1"
}
Observe that the created object, a React element, possesses the
following properties — key,
props, ref,
type; but we will not delve into any of it
right now.
ReactDOM.render() then renders this object
into the div element with
id="root" inside
public/index.html.
ReactJS <Hello/> component rendered in browser
Functional Components
Let us define a simple JavaScript function called
Hello() which returns the above
<h1>Hello, World!</h1> JSX
code. To pass this JSX into
ReactDOM.render() we need to pass our
Hello() function as
<Hello/> into
ReactDOM.render(). This has the same
effect as above where the JSX is passed directly into
ReactDOM.render() and gets rendered in
the browser.
function Hello() {
return <h1>Hello, World!</h1>;
}
ReactDOM.render(<Hello/>, document.getElementById('root'));
We can rewrite our Hello() function
using the recent ES6 arrow function expression (=>
token) as shown below.
const Hello = () => {
return (
<h1>Hello, World!</h1>
);
}
ReactDOM.render(<Hello/>, document.getElementById('root'));
Components as such which are pure JavaScript functions are known as Functional Components.
Class Components
We can define components as
ES6 classes
too. For example, the above
Hello() function can also be defined as
a subclass of React.Component as shown
below.
class Hello extends React.Component {
render() {
return <h1>Hello, World!</h1>;
}
}
ReactDOM.render(<Hello/>, document.getElementById('root'));
The render() method is the only
necessary method for a subclass of
React.Component to define inside it.
There can be many other methods besides
render(), but they are all optional.
Components which are defined as ES6 classes are known as
Class Components.
Props
Now since Hello() is a function, we can
pass arguments to it. We modify it a little to pass one argument to
it — an object called
props ("props" means properties). Our
props object has a property called name.
The name property is passed as an
attribute with the value "Agnes".
function Hello(props) {
return <h1>Hello, {props.name}!</h1>;
}
ReactDOM.render(<Hello name="Agnes"/>, document.getElementById('root'));
ReactJS component with props
Props can be a string, an integer, an array, an object or even a function.
The class version of the above component with props is as below.
class Hello extends React.Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}
ReactDOM.render(<Hello name="Agnes"/>, document.getElementById('root'));
defaultProps
We need not always pass props to a component as an attribute-value
pair. There is a function called
defaultProps() which allows us to
"bypass" it.
class Hello extends React.Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}
Hello.defaultProps = {
name: 'Agnes'
};
ReactDOM.render(<Hello/>, document.getElementById('root'));
Difference between Functional Components and Class Components
Both functional components and class components have
props, an immutable object which comes
from parent components. But there is one fundamental difference
between them: class components have an additional object know as
state, which has its scope limited only to the current
component. We will learn more about them in detail
here.