Components & Props
# 03. Components & Props
# Function and Class Components
# 1. Function Components
function Welcome(props){
return <h1>Hello, {props.name}</h1>
}
2
3
This function is a valid React component. It accepts a single props argument with data and returns a React element.
# 2. Class Components
Defined using ES6 class:
class Welcome extends React.Component{
// The render method describes what you want to see on screen
render() {
return <h1>Hello, {this.props.name}</h1>
}
}
2
3
4
5
6
The above two components are equivalent.
# Differences in Event Handling Between Function and Class Components
In a
class component:onClick={() => this.props.onClick()}In a
function component:onClick={props.onClick}(note: no parentheses on either side).
# Rendering a Component (Parent-to-Child Data Passing)
React elements can also be user-defined components:
const element = <Welcome name="Sara" />;
Pass values to child components through attributes:
function Welcome(props) { // Receive values via props
return <h1>Hello, {props.name}</h1>;
}
const element = <Welcome name="Sara" />; // Pass values via attributes
ReactDOM.render(
element,
document.getElementById('root')
);
2
3
4
5
6
7
8
9
Note: Component names must start with a capital letter.
React treats components starting with lowercase letters as DOM tags. For example, <div /> represents an HTML div tag, while <Welcome /> represents a component and requires Welcome to be in scope.
# Composing Components (Reusing Components)
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
function App() {
return (
<div>
// Reusing the Welcome component
<Welcome name="Sara" />
<Welcome name="Cahal" />
<Welcome name="Edite" />
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Typically, the top-level component of every new React application is the
Appcomponent.
# Extracting Components (Splitting Components)
Consider the following Comment component:
function Comment(props) {
return (
<div className="Comment">
<div className="UserInfo">
<img className="Avatar"
src={props.author.avatarUrl}
alt={props.author.name}
/>
<div className="UserInfo-name">
{props.author.name}
</div>
</div>
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
This component is hard to maintain due to nesting, and it's difficult to reuse its individual parts. Let's extract some components from it.
First, extract the Avatar component:
function Avatar(props) {
return (
<img className="Avatar"
src={props.user.avatarUrl}
alt={props.user.name}
/>
);
}
2
3
4
5
6
7
8
# Props Naming Principle
Avatar doesn't need to know that it is being rendered inside a Comment. This is why we gave its prop a more generic name: user rather than author.
We recommend naming props from the component's own perspective rather than the context in which it is being used.
Next, we'll extract a UserInfo component that renders an Avatar next to the user's name:
function UserInfo(props) {
return (
<div className="UserInfo">
<Avatar user={props.user} />
<div className="UserInfo-name">
{props.user.name}
</div>
</div>
);
}
2
3
4
5
6
7
8
9
10
The final Comment component:
function Comment(props) {
return (
<div className="Comment">
<UserInfo user={props.author} />
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
2
3
4
5
6
7
8
9
10
11
12
13
Extracting components might seem like tedious work at first, but having a palette of reusable components is absolutely worth it in larger apps.
# Extraction Guidelines
- Parts of the UI that are used in multiple places
- A sufficiently complex component (page)
# Props Are Read-Only (Cannot Modify Props)
Whether you declare a component as a function or a class (opens new window), it must never modify its own props.
Of course, application UIs are dynamic and change over time. In the next section (opens new window), we will introduce a new concept called "state". State allows React components to change their output over time in response to user actions, network responses, and anything else, without violating this rule.