IV. Componentization and Properties (props)

IV. Componentization and Properties (props)

Components allow you to split the UI into separate reusable parts and consider each part separately. Conceptually, components are like JavaScript functions. They accept any input (called "props") and return the React element that should appear on the screen.

Functional and class components

The simplest way to define components is to write JavaScript functions:

function Welcome(props) {
    return <h1>hello, {props.name}</h1>
}

This function is a valid React component because it receives a "props" object with data as a parameter and returns a React element. We call these components "functional" because they are JavaScript functions.

You can also use the ES6 class to define components:

class Welcome extends React.Component {
    render() {
        return <h1>hello, {this.props.name}</h1>;
    }
}

These two components are equivalent from the perspective of React.

Class components have some additional functions, which we will discuss in the following sections. Until then, we will simply use functional components.

Rendering a Component

Previously, we only encountered React elements using DOM tags:

const element = <div />;

However, elements can also represent user-defined components:

const element = <Welcome name="zhangyatao" />;

When React sees an element representing a user-defined component, it passes the attributes of the JSX tag into an object to the component. We call this object "props".

For example, this code renders "Hello, zhangyatao" on the page:

function Welcome(props) {
    return <h1>Hello, {props.name}</h1>;
}

const element = <Welcome name="zhangyatao" />;
ReactDOM.render(
    element,
    document.getElementById('root')
);

Let's review what happened in this example:

  1. First, call the ReactDOM.render() method and process < Welcome (). name = zhangyatao "/> component.

  2. React uses {name:'zhangyatao'} as props to invoke the Welcom component.

  3. Our Welcom component returns a <h1>. Hello, zhangyatao </ H1 > element as result.

  4. React DOM effectively according to <h1> Hello, zhangyatao </ H1 > to update DOM.

warning
Component names are always capitalized.
For example, < div /> denotes a DOM tag, but < Welcome /> Represents a component and requires Welcom to be in scope with ReactDOM.

Writing Components

Components can refer to other components in their return values. This allows us to use the same component abstraction for details at any level. A button, a form, a dialog box, and a screen: In React applications, all these are usually represented as components.
For example, we can create an App component that renders multiple Welcome components:

function Welcome(props) {
   return <h1>Hello, {props.name}</h1>;
}

function App() {
   return (
       <div>
           <Welcome name="zhangyatao" />
           <Welcome name="jiangyanyun" />
           <Welcome name="pangyun" />
       </div>
   );
}

ReactDOM.render(
   <App />,
   document.getElementById('root')
);

The new React application has a separate App component at the top.  
However, if you integrate React into existing applications, you can use small components such as Button to start from the bottom up and gradually move up to the top of the view hierarchy.

warning
References to multiple components must be wrapped and returned in a root element. That's why we added a <div> to include all <Welcome>. /> Elements.

Extraction assembly

Never be afraid to split components into smaller components.
For example, consider the Comment component:

import React from 'react';
import ReactDOM from 'react-dom';

function formatDate(date) {
    return date.toISOString();
}

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>
    );
}

ReactDOM.render(
    <Comment author={{
        avatarUrl: 'https://ss0.bdstatic.com/7Ls0a8Sm1A5BphGlnYG/sys/portrait/item/3ae1dc06.jpg',
        name: 'zhangyatao'
    }} text={'My name is Zhang Yatao.'} date={new Date()}/>,
    document.getElementById('root')
);

It accepts author (author), text (content) and date (date) as props to describe comments on social media sites.
This component may be difficult to change, because all nested, it is also difficult to reuse a single part of it. Let's extract several components from it.

First, we will extract avatar:

function Avatar(props) {
    return (
        <img className="Avatar"
            src={props.user.avatarUrl}
            alt={props.user.name}
        />
    );
}

avatar does not need to know that it is being presented in Comment. That's why we give it a more generic name for prop: user rather than author.
We recommend naming props from the component's own perspective, rather than using its context.

We can now simplify Comment components a little bit:

function Comment(props) {
    return (
        <div className="Comment">
            <div className="UserInfo">
                <Avatar user={props.author} />
                <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>
    );
}

Next, we will extract a UserInfo component that renders an avatar next to the user name:

function UserInfo(props) {
    return (
        <div className="UserInfo">
            <avatar uer={props.user} />
            <div className="UserInfo-name">
                {props.user.name}
            </div>
        </div>
    );
}

This allows us to further simplify Comment components:

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>
    );
}

The final code is as follows:

import React from 'react';
import ReactDOM from 'react-dom';

function formatDate(date) {
    return date.toISOString();
}
function Avatar(props) {
    return (
        <img className="Avatar"
             src={props.user.avatarUrl}
             alt={props.user.name}
        />
    );
}
function UserInfo(props) {
    return (
        <div className="UserInfo">
            <Avatar user={props.user}/>
            <div className="UserInfo-name">
                {props.user.name}
            </div>
        </div>
    );
}
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>
    );
}
ReactDOM.render(
    <Comment author={{
        avatarUrl: 'https://ss0.bdstatic.com/7Ls0a8Sm1A5BphGlnYG/sys/portrait/item/3ae1dc06.jpg',
        name: 'zhangyatao'
    }} text={'My name is Zhang Yatao.'} date={new Date()}/>,
    document.getElementById('root')
);

In the process of delivering reusable components to large applications, pulling out components may initially look like dirty and tiring work. So there's a good rule of thumb: if a part of the UI is used several times (buttons, panels, avatars), or something that's more complicated inside (App, FeedStory, comments), a reusable component can make the most of it.

Props is read-only

Whether it declares a component as a functional component or a class component, it cannot modify its props. Consider this function for calculating the sum of parameters:

function sum(a, b) {
    return a + b;
}

Such functions are called "pure functions" because they do not change their parameter values and always return the same results for the same input.
On the contrary, this function is impure because it changes its parameters:

function withdraw(account, amount) {
    account.total -= amount;
}

React is very flexible, but it has a strict rule:
All React components must run as pure functions of their porps.

Of course, most UI s in applications are dynamic and change over time. In the next section, we will introduce a new concept of "state". State allows React components to respond to user actions, network responses, and anything else, changing their output over time without violating this rule.

Keywords: React Javascript network

Added by Comtemplative on Tue, 18 Jun 2019 03:14:45 +0300