1. Why does the React DOM use camelCase to define property names?

Because JSX is syntactically closer to JavaScript than HTML, the React DOM uses camelCase (small camel name) to define attribute names rather than the naming convention for HTML attribute names.

For example, the class in JSX becomes className and tabIndex becomes TabIndex.

JSX prevents injection attacks

You can safely insert user input into JSX:

const title = response.potentiallyMaliciousInput;
// It is safe to use directly:
const element = <h1>{title}</h1>;
Copy the code

The React DOM escapes by default before rendering all input. It ensures that you never inject content into your application that you didn’t explicitly write. All content is converted to a string before rendering. This effectively prevents XSS (cross-site scripting) attacks.

React elements and components

Unlike the browser DOM element, the React element is a generic object created with minimal overhead. The React DOM takes care of updating the DOM to be consistent with the React element.

The element is the smallest brick that makes up the React application. The element describes what you want to see on the screen.

const element = <h1>Hello, world</h1>;
Copy the code

Components are made up of elements.

4. The Root DOM node is managed by the React DOM

Let’s say you have a

somewhere in your HTML file
<div id="root"></div>
Copy the code

We call this the “root” DOM node, because everything inside that node will be managed by the React DOM. To render a React element into the root DOM node, simply pass them together to reactdom.render ().

const element = <h1>Hello, world</h1>;
ReactDOM.render(element, document.getElementById('root'));
Copy the code

React elements are immutable objects

React elements are immutable objects. Once created, you can’t change its child elements or attributes. An element is like a single frame of a movie: it represents the UI at a particular moment.

Based on what we already know, the only way to update the UI is to create a brand new element and pass it to reactdom.render ().

In practice, most React applications only call reactdom.render () once.

React only updates what it needs to update

The React DOM compares elements and their children to their previous states and only makes necessary updates to bring the DOM to the expected state.

Although every second we create a new element that describes the entire UI tree, the React DOM only updates what’s actually changed.

7, components,

Note: Component names must begin with a capital letter.

React will treat components that begin with a lowercase letter as native DOM tags. For example,

represents an HTML div tag, while
represents a component and needs to use Welcome in scope.

You can learn more about the reasons for this specification in in-depth JSX.

Function components and class components

Function component: This function is a valid React component because it takes a unique “props” (for properties) object with data and returns a React element. This type of component is called a “function component” because it is essentially a JavaScript function.

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

ES6 class components

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

Native DOM tag components and user-defined components

Native DOM tag components

const element = <div />;
Copy the code

User-defined components:

const element = <Welcome name="Sara" />;
Copy the code

When the React element is a user-defined component, it converts attributes and children received by JSX into a single object passed to the component, which is called “props.”

Compose components versus extract components

Components can reference other components in their output, and in general, the top component of every new React application is an App component.

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

function App() {
  return (
    <div>
      <Welcome name="Sara" />
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  );
}

ReactDOM.render(
  <App />.document.getElementById('root'));Copy the code

Extract components and break them up into smaller components. Extracting components may seem like a lot of work at first, but in large applications, building reusable component libraries is well worth it. As a rule of thumb, if part of the UI is used multiple times (Button, Panel, Avatar), or if the component itself is complex enough (App, FeedStory, Comment), then it is a good candidate for extracting individual components.

8. Read-only of Props

A component must never modify its props, either using a function declaration or through a class declaration. Such a function is called a “pure function” because it does not attempt to change the input parameter, and the same input parameter returns the same result multiple times.

React is very flexible, but it also has a strict rule:

All React components must protect their props from being changed like pure functions.

9, the state

Without violating the rules of the props section, state allows the React component to dynamically change its output in response to user actions, network responses, or other changes.

State is similar to props, but State is private and fully controlled by the current component.

The Render method is called every time a component is updated, but as long as the component is rendered in the same DOM node, only one class instance of the component is created and used.

Change the function component to a class component step

function Clock(props) {
  return (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {props.date.toLocaleTimeString()}.</h2>
    </div>
  );
}

function tick() {
  ReactDOM.render(
    <Clock date={new Date()} / >.document.getElementById('root')); }setInterval(tick, 1000);
Copy the code
  1. The following five steps convert the Clock function component into a class component:
    • Create an ES6 class with the same name and inherit fromReact.Component.
    • Add an emptyrender()Methods.
    • Move the function body torender()In the method.
    • inrender()Method.this.propsreplaceprops.
    • Delete the remaining empty function declarations.
  2. Add a local state to the class component by moving date from props to state in three steps:
    • therender()In the methodthis.props.datereplacethis.state.date.
    • Add a class constructor, and in that function forthis.stateTo initialize, pass props to the constructor of the parent class in the following waysuperIn the function. A Class component should always call the parent constructor with the props argument
    • Removes the date attribute from the element
  3. Add lifecycle methods to a Class and declare special methods for a Class component that will be executed when the component is mounted or unmounted:
    • When the Clock component is first rendered into the DOM, a timer is set for it. “To mount
      • The componentDidMount() method runs after the component has been rendered into the DOM, so it’s a good idea to set a timer here
    • Also, the timer should be cleared when the Clock component is removed from the DOM. “Unmount”
    • usethis.setState()To update component state from time to time

Although this.props and this.state are set by React itself and have special meanings, you can add extra fields to the class that don’t participate in the data flow (such as timer ID)

It is important to free up resources when a component is destroyed.

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date(a)}; }componentDidMount() {
    this.timerID = setInterval(
      () = > this.tick(),
      1000
    );
  }

  componentWillUnmount() {
    clearInterval(this.timerID);
  }

  tick() {
    this.setState({
      date: new Date()}); }render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />.document.getElementById('root'));Copy the code

What happens and the order in which these methods are called:

  1. when<Clock />Are passed toReactDOM.render()React calls the Clock component’s constructor. Because Clock needs to display the current time, it uses one that contains the current timeObject to initialize this.state. We will update state later.
  2. And then React will call itThe component’s render()Methods. This is how React determines what to display on the page. Then the ReactUpdate the DOMTo match the output rendered by Clock.
  3. When the Clock output is inserted into the DOMReact will call itComponentDidMount()Lifecycle methods. In this method, the Clock component asks the browser to set a timer to call the component’s every secondtick()Methods.
  4. The browser calls it every secondtick()Methods. In this method, the Clock component is calledsetState()To plan a UI update.Thanks to thesetState()React will know that the state has changed, and will recall the Render () method to determine what to display on the pageThis time,render()In the methodthis.state.dateThis will render out the updated time. React also updates the DOM accordingly.
  5. Once the Clock component is removed from the DOMReact will call itcomponentWillUnmount()Lifecycle method, so the timer stops.

There are three things you should know about setState() :

Do not modify State directly

For example, this code does not re-render the component:

// Wrong
this.state.comment = 'Hello';
Copy the code

Instead, use setState():

// Correct
this.setState({comment: 'Hello'});
Copy the code

The constructor is the only place you can assign a value to this.state

Updates to State can be asynchronous

React may combine multiple setState() calls into a single call for performance reasons.

Because this.props and this.state may update asynchronously, you should not rely on their values to update the next state.

For example, this code might fail to update counters:

// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});
Copy the code

To solve this problem, make setState() accept a function instead of an object. This function uses a state as the first parameter and props as the second parameter when the update was applied:

// Correct
this.setState((state, props) = > ({
  counter: state.counter + props.increment
}));
Copy the code

The arrow function was used above, but the normal function works just as well:

// Correct
this.setState(function(state, props) {
  return {
    counter: state.counter + props.increment
  };
});
Copy the code

Updates to the State are merged into the current State and are shallow merged

When you call setState(), React merges the objects you provide into the current state. For example, your state contains several independent variables:

  constructor(props) {
    super(props);
    this.state = {
      posts: [].comments: []}; }Copy the code

You can then call setState() to update them individually:

  componentDidMount() {
    fetchPosts().then(response= > {
      this.setState({
        posts: response.posts
      });
    });

    fetchComments().then(response= > {
      this.setState({
        comments: response.comments
      });
    });
  }
Copy the code

The merge here is shallow, so this.setState({comments}) keeps this.state.posts intact, but replaces this.state.comments completely.

11. Why is state local or encapsulated?

Neither parent nor child components know whether a component is stateful or stateless, and they do not care whether it is a function component or a class component.

None of the components are accessible except those that have and have state set.

12. Data flows downward

A component can optionally pass its state as props to its child components as attributes, and the child components will receive the parameters as attributes in its props, but the component itself has no way of knowing that it is derived from the parent component’s state. Or props of the parent component, or entered manually.

This is often referred to as “top-down” or “one-way” data flow. Any state is always owned by a particular component, and any data or UI derived from that state can only affect components “below” them in the tree.

If you think of a tree of components as a waterfall of props, then the state of each component is like adding additional water to the waterfall at any point, but it can only flow down.

Component instances are truly independent

These three
components are truly independent.

function App() {
  return (
    <div>
      <Clock />
      <Clock />
      <Clock />
    </div>
  );
}

ReactDOM.render(
  <App />.document.getElementById('root'));Copy the code

React event handling differs from DOM event handling

The React element’s event handling is similar to the DOM element’s, but there are a few syntactic differences:

  1. React events are named in a camelCase rather than pure lowercase.
  2. To use JSX syntax you need to pass in a function as an event handler, not a string.
  3. Another difference in React is that you can’t prevent default behavior by returning false. You have to use it explicitlypreventDefault

Traditional HTML

<button onclick="activateLasers()">
  Activate Lasers
</button>
<a href="#" onclick="console.log('The link was clicked.'); return false">
  Click me
</a>
Copy the code

React is a little different

Function component

function ActionLink() {
  function handleClick(e) {                     // e is a composite event
    e.preventDefault();
    console.log('The link was clicked.');
  }

  return (
    <div>
      <button onClick={activateLasers}>
        Activate Lasers
      </button>
      <a href="#" onClick={handleClick}>
        Click me
      </a>
    </div>
  );
}
Copy the code

Class component (3 method bindingsthis)

You have to be careful with this in the JSX callback. In JavaScript, class methods do not bind this by default. If you forget to bind this.handleClick and pass it in onClick, this will be undefined when you call this function.

This isn’t React specific behavior; This has to do with how JavaScript functions work.

In general, if you don’t add () to the end of a method, such as onClick={this.handleclick}, you should bind this to the method

1. Declare event handlers as methods in class
class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    // This binding is necessary in order to use 'this' in callbacks
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(state= > ({
      isToggleOn: !state.isToggleOn
    }));
  }

  render() {
    return (
    // this. HandleClick calls must bind this in the constructor
      <button onClick={this.handleClick}>      
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

ReactDOM.render(
  <Toggle />.document.getElementById('root'));Copy the code
2. If you find using BIND too cumbersome, you can use the experimental version that is being usedpublic class fieldsgrammar

Create React App enables this syntax by default.

class LoggingButton extends React.Component {
  // This syntax ensures that 'this' in' handleClick 'is bound.
  // Note: this is * experimental * syntax.
  handleClick = () = > {
    console.log('this is:'.this);
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        Click me
      </button>); }}Copy the code
3. If you do not use the class fields syntax, you can use it in the callbackArrow function

The problem with this syntax is that different callback functions are created each time you render.

In most cases, this is fine, but if the callback function is passed as a prop to child components, they may do additional re-rendering.

We generally recommend binding or using the Class Fields syntax in the constructor to avoid such performance problems.

class LoggingButton extends React.Component {
  handleClick() {
    console.log('this is:'.this);
  }

  render() {
    // This syntax ensures that 'this' in' handleClick 'is bound.
    return (
      <button onClick={()= > this.handleClick()}>
        Click me
      </button>); }}Copy the code

15. How do I pass parameters to event handlers?

If id is the ID of the row you want to delete, you can pass arguments to the event handler in either of the following ways:

<button onClick={(e) = > this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)} >Delete Row</button>
Copy the code

The two approaches are equivalent and are implemented using the arrow Function and function.prototype.bind respectively.

In both cases, the React event object E is passed as the second argument.

If the arrow function is used, the event object must be passed explicitly, whereas if bind is used, the event object and more parameters are passed implicitly.

16. Three ways of conditional rendering

  1. if-else
  2. And the operator.&&
  3. Ternary operatorcondition ? true : false

The element variables

Use variables to store elements. It helps you conditionally render one part of a component without changing the rest of the rendering.

1. if-else

A stateful component of LoginControl.

It will render
or
depending on the current state

class LoginControl extends React.Component {
  constructor(props) {
    super(props);
    this.handleLoginClick = this.handleLoginClick.bind(this);
    this.handleLogoutClick = this.handleLogoutClick.bind(this);
    this.state = {isLoggedIn: false};
  }

  handleLoginClick() {
    this.setState({isLoggedIn: true});
  }

  handleLogoutClick() {
    this.setState({isLoggedIn: false});
  }

  render() {
    const isLoggedIn = this.state.isLoggedIn;
    let button;  // Element variables
    if (isLoggedIn) {
      button = <LogoutButton onClick={this.handleLogoutClick} />;
    } else {
      button = <LoginButton onClick={this.handleLoginClick} />;
    }

    return (
      <div>
        <Greeting isLoggedIn={isLoggedIn} />
        {button}
      </div>
    );
  }
}

ReactDOM.render(
  <LoginControl />.document.getElementById('root'));Copy the code

2. The and operator&&

You can embed expressions in JSX by wrapping code in curly braces.

In JavaScript, true && expression always returns expression, and false && expression always returns false.

Therefore, if the condition is true, the element to the right of && will be rendered, if it is false, React will ignore and skip it.

Note that an expression that returns false causes the element after && to be skipped but returns a false expression. In the following example, the render method returns

0

.

function Mailbox(props) {
  const unreadMessages = props.unreadMessages;
  const count = 0;
  return (
    <div>
      <h1>Hello!</h1>
      { count && <h1>Messages: {count}</h1>} // Returns'<h1>Hello!</h1> 0 ...`
      {unreadMessages.length > 0 &&
        <h2>
          You have {unreadMessages.length} unread messages.
        </h2>
      }
    </div>
  );
}

const messages = ['React'.'Re: React'.'Re:Re: React'];
ReactDOM.render(
  <Mailbox unreadMessages={messages} />.document.getElementById('root'));Copy the code

3. Ternary operatorscondition ? true : false

render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    <div>
    	The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
      {isLoggedIn
        ? <LogoutButton onClick={this.handleLogoutClick} />
        : <LoginButton onClick={this.handleLoginClick} />
      }
    </div>
  );
}
Copy the code

Preventing component rendering

In rare cases, you may want to hide a component even if it has been rendered by another component. To do this, you can have the Render method return NULL directly without doing any rendering.

function WarningBanner(props) {
  if(! props.warn) {return null;             // The render method returns null without doing any rendering
  }

  return (
    <div className="warning">
      Warning!
    </div>
  );
}

class Page extends React.Component {
  constructor(props) {
    super(props);
    this.state = {showWarning: true};
    this.handleToggleClick = this.handleToggleClick.bind(this);
  }

  handleToggleClick() {
    this.setState(state= > ({
      showWarning: !state.showWarning
    }));
  }

  render() {
    return (
      <div>
        <WarningBanner warn={this.state.showWarning} />
        <button onClick={this.handleToggleClick}>
          {this.state.showWarning ? 'Hide' : 'Show'}
        </button>
      </div>
    );
  }
}

ReactDOM.render(
  <Page />.document.getElementById('root'));Copy the code

17,Why does the list have to contain a specialkeyAttribute?

Warning a key should be provided for list items, which means that when you create an element, you must include a special key property.

Key helps React identify which elements have changed, such as being added or removed. So you should give each element in the array a definite identity.

The key will pass information to React, but not to your components. Could not read props. Key.

If you need the value of the key attribute in your component, pass it explicitly with another attribute name.

An element’s key should ideally be a unique string that the element has in the list. Typically, we use the ID in the data as the element’s key.

The key must only be unique between sibling nodes

A key used in an array element should be unique among its siblings. However, they need not be globally unique. When we generate two different arrays, we can use the same key.

Example:

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) = >
    <ListItem key={number.toString()}
              value={number} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}
Copy the code

Is equivalent to:

function NumberList(props) {
  const numbers = props.numbers;
  return (
    <ul>
      {numbers.map((number) =>
        <ListItem key={number.toString()}
                  value={number} />
      )}
    </ul>
  );
}
Copy the code

JSX allows you to embed any expression in curly braces, which can sometimes make your code cleaner, but sometimes this style can be abused. Just as in JavaScript, it’s entirely up to you when you need to extract a variable for readability. But keep in mind that if a map() has too many levels nested, that might be a good time to extract components.

18. Why not use index as key?

As a last resort, you can use the element index as the key when the element has no specified ID. If the order of list items may change, we do not recommend using an index as a key value, as this can lead to poor performance and possibly component state issues. Check out Robin Pokorny’s in-depth analysis of the negative effects of using indexes as keys. If you choose not to specify an explicit key, React will default to using the index as the key for list items.

19, lists,keyPosition of property

The element’s key makes sense only if it is placed in the context of the nearest array.

For example, if you extract a ListItem component, you should keep the key on the element in the array, not on the

  • element in the ListItem component.
  • function ListItem(props) {
      const value = props.value;
      return (
        / / error! You don't need to specify key here:
        <li key={value.toString()}>
          {value}
        </li>
      );
    }
    
    function NumberList(props) {
      const numbers = props.numbers;
      const listItems = numbers.map((number) = >
        / / error! The element's key should be specified here:
        <ListItem value={number} />
      );
      return (
        <ul>
          {listItems}
        </ul>
      );
    }
    
    const numbers = [1.2.3.4.5];
    ReactDOM.render(
      <NumberList numbers={numbers} />.document.getElementById('root'));Copy the code

    A good rule of thumb is that elements in the map() method need a key attribute.

    function ListItem(props) {
      / / right! There is no need to specify key:
      return <li>{props.value}</li>;
    }
    
    function NumberList(props) {
      const numbers = props.numbers;
      const listItems = numbers.map((number) = >
        / / right! The key should be specified in the context of the array
        <ListItem key={number.toString()} value={number} />
      );
      return (
        <ul>
          {listItems}
        </ul>
      );
    }
    
    const numbers = [1.2.3.4.5];
    ReactDOM.render(
      <NumberList numbers={numbers} />.document.getElementById('root'));Copy the code

    Build React applications in composite mode

    React has a very powerful combination mode. We recommend using composition rather than inheritance to achieve code reuse between components. How to solve these problems by combining ideas.

    1. Containment relationships — used when considering “generic containers”

    Some components do not know the details of their child components in advance.

    This is especially true in the Sidebar and Dialog components that represent general-purpose containers.

    props.children

    We recommend that these components use a special Children Prop to pass their child components into the render result:

    function FancyBorder(props) {
      return (
        <div className={'FancyBorder FancyBorder-'+props.color} >
          {props.children}
        </div>
      );
    }
    Copy the code

    This allows other components to be nested through JSX, passing any component to them as a child component.

    function WelcomeDialog() {
      return (
        <FancyBorder color="blue">
          <h1 className="Dialog-title">
            Welcome
          </h1>
          <p className="Dialog-message">
            Thank you for visiting our spacecraft!
          </p>
        </FancyBorder>
      );
    }
    Copy the code

    Everything in the

    JSX tag is passed to the FancyBorder component as a children Prop. Because FancyBorder renders {props. Children} in a

    , these child components that are passed will all end up in the output.

    propsThe concept of “slots” in other libraries

    In rare cases, you may need to reserve several “holes” in a component. In this case, instead of using children, we can make a convention ourselves: pass the required content to props and use the appropriate prop.

    function SplitPane(props) {
      return (
        <div className="SplitPane">
          <div className="SplitPane-left">
            {props.left}
          </div>
          <div className="SplitPane-right">
            {props.right}
          </div>
        </div>
      );
    }
    
    function App() {
      return (
        <SplitPane
          left={
            <Contacts />
          }
          right={
            <Chat />} / >
      );
    }
    Copy the code

    2. Special instance relationship

    Sometimes we think of components as special instances of other components, and we can customize and render a “general” component to get a “special instance” component.

    function Dialog(props) {
      return (
        <FancyBorder color="blue">
          <h1 className="Dialog-title">
            {props.title}
          </h1>
          <p className="Dialog-message">
            {props.message}
          </p>
        </FancyBorder>
      );
    }
    
    function WelcomeDialog() {
      return (
        <Dialog
          title="Welcome"
          message="Thank you for visiting our spacecraft!" />
      );
    }
    Copy the code

    Comprehensive example

    function Dialog(props) {
      return (
        <FancyBorder color="blue">
          <h1 className="Dialog-title">
            {props.title}
          </h1>
          <p className="Dialog-message">
            {props.message}
          </p>
          {props.children}
        </FancyBorder>
      );
    }
    
    class SignUpDialog extends React.Component {
      constructor(props) {
        super(props);
        this.handleChange = this.handleChange.bind(this);
        this.handleSignUp = this.handleSignUp.bind(this);
        this.state = {login: ' '};
      }
    
      render() {
        return (
          <Dialog title="Mars Exploration Program"
                  message="How should we refer to you?">
            <input value={this.state.login}
                   onChange={this.handleChange} />
            <button onClick={this.handleSignUp}>
              Sign Me Up!
            </button>
          </Dialog>
        );
      }
    
      handleChange(e) {
        this.setState({login: e.target.value});
      }
    
      handleSignUp() {
        alert(`Welcome aboard, The ${this.state.login}! `); }}Copy the code

    React Philosophy

    One of the best parts of React is getting us thinking, how do you build an application

    Hook associated

    Hook is a new feature in React 16.8.

    Pay attention to

    React 16.8.0 was the first release to support hooks. When upgrading, be sure to update all packages, including the React DOM. React Native supports hooks starting with version 0.59.

    1. Why Hook?

    It lets you use state and other React features without having to write a class.