Code for the first time hello World

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

React is a JavaScript library.

What is JSX?

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

This tag syntax is neither string nor HTML, it is called JSX and is a syntax extension of JavaScript. It is recommended, but not mandatory, to use JSX in React, as it does a good job of showing the nature of the interaction that UL wants. It reminds you of a template language, but it has all the functionality of JavaScript.

Why use JSX?

React argues that rendering logic is intrinsically coupled to other UL logic, such as binding processing time in UL, notifying UL when state changes at certain moments, and displaying prepared data in UL.

In JSX syntax, you can place any valid JavaScript expression inside curly braces

const name = 'Josh Perez';const element = <h1>Hello, {name}</h1>;
ReactDOM.render(
  element,
  document.getElementById('root'));Copy the code
function formatName(user) {
  return user.firstName + ' ' + user.lastName;
}

const user = {
  firstName: 'Harper'.lastName: 'Perez'
};

const element = (
  <h1>
    Hello, {formatName(user)}!  </h1>
);

ReactDOM.render(
  element,
  document.getElementById('root'));Copy the code

JSX is itself an expression

After compilation, the JSX expression is turned into a normal JavaScript function call and evaluated to get a JavaScript object.

That is, you can use JSX in blocks of code in if statements and for loops, assign JSX to variables, pass JSX as an argument, and return JSX from functions:

function getGreeting(user) {
  if (user) {
    return <h1>Hello, {formatName(user)}!</h1>;  }
  return <h1>Hello, Stranger.</h1>; }Copy the code

JSX specific properties

You can specify attribute values as string literals by using quotes:

const element = <div tabIndex="0"></div>;
Copy the code

We can also use curly braces to insert a JavaScript expression inside the attribute value:

const element = <img src={user.avatarUrl}></img>;
Copy the code

When embedding JavaScript expressions in attributes, do not enclose quotation marks around braces. You should only use either quotation marks (for string values) or braces (for expressions). You cannot use both symbols for the same attribute.

Warning: 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.Copy the code

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.

JSX stands for object

Babel translates JSX into a function call called react.createElement ().

The following two examples of code are exactly equivalent:

const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);

const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world! '
);

Copy the code

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.

Consider an example of a timer:


function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  ReactDOM.render(element, document.getElementById('root')); }setInterval(tick, 1000);

Copy the code

Although every second we create a new element that describes the entire UI tree, the React DOM only updates what actually changes, which is the text node in the example.

In our experience, we should focus on the state of the UI at any given moment, rather than uniformly modifying the entire interface over time.

Components & Props

A component is conceptually similar to a JS function that takes arbitrary inputs (props) and returns a React element that describes what the page displays.

Function components and class components

The easiest way to define a component is to write a JavaScript function:

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

This function is a valid React component because it takes only the “props” (representing 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.

You can also use ES6 classes to define components:

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

The above two components are equivalent in React.

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

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

Let’s review what happens in this example: 1. We call reactdom.render () and pass in
as an argument.

2. React calls the Welcome component and passes {name: ‘Sara’} as props.

3. The Welcome component returns < H1 >Hello, Sara
elements.

4. React DOM Updates the DOM efficiently to

Hello, Sara

.

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.

Read-only of Props

A component must never modify its props, either using a function declaration or through a class declaration. Consider the sum function:

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

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.

In contrast, the following function is not pure because it changes its input parameter:

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

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

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

State & Life cycle

Convert a function component to a class component

To convert the Clock function component into a class component, perform the following five steps:

1/ Create an ES6 class with the same name that inherits from react.component.exe.

2/ Add an empty render() method.

3/ Move the function body into the render() method.

4/ Replace props with this.props in render().

5/ Remove the remaining empty function declarations.

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>); }}Copy the code

** Adds local state ** to the class component

We move date from props to state in three steps:

Replace this.props. Date with this.state.date in render() :

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>      </div>); }}Copy the code

Add a class constructor and assign an initial value to this.state:

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date(a)}; }render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>); }}Copy the code

Pass props to the constructor of the parent class as follows:

  constructor(props) {
    super(props);    this.state = {date: new Date(a)}; }Copy the code

A Class component should always call the parent constructor with the props argument. Remove date attribute from element:

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

Complete code:

class Clock extends React.Component {
  constructor(props) {    super(props);    this.state = {date: new Date(a)}; }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

** Adds the lifecycle method to Class **

When the Clock component is first rendered into the DOM, a timer is set for it. This is called a “mount” in React.

Also, the timer should be cleared when the Clock component is removed from the DOM. This is called unmount in React.

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date(a)}; }// The mount method runs after the component has already been rendered into the DOM, so it is best to set the timer here
  componentDidMount() { 
      this.timerID = setInterval(      
      () = > this.tick(),      
      1000);
  }
  / / unloading
  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>); }}Copy the code

Let’s have a quick overview of what happens and the order in which these methods are called:

When passed to reactdom.render (), React calls the Clock component’s constructor. Because Clock needs to display the current time, it initializes this.state with an object containing the current time. We will update state later.

React then calls the render() method of the component. This is how React determines what to display on the page. React then updates the DOM to match the output of the Clock rendering.

When the output of Clock is inserted into the DOM, React calls the ComponentDidMount() lifecycle method. In this method, the Clock component asks the browser to set a timer to call the component’s tick() method once per second.

The browser calls the tick() method once every second. In this method, the Clock component plans a UI update by calling setState(). Thanks to the call to setState(), React knows that state has changed and will recall the Render () method to determine what to display on the page. This time, the this.state.date in the render() method is different, which renders the updated time. React also updates the DOM accordingly.

Once the Clock component is removed from the DOM, React calls the componentWillUnmount() lifecycle method, which stops the timer.

** Uses State ** correctly

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

**State updates 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

**State updates are merged **

When you call setState(), React merges the objects you provide into the current state.

  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

Data flows downward

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.

This is why state is called local or encapsulated. No component is accessible except the component that owns and sets it.

A component can optionally pass its state as props down to its child components:

<FormattedDate date={this.state.date} />
Copy the code

The FormattedDate component receives the date argument in its props, but the component itself has no way of knowing whether it is from the Clock’s state, or the Clock’s props, or if it was entered manually:

function FormattedDate(props) {
  return <h2>It is {props.date.toLocaleTimeString()}.</h2>;
}
Copy the code

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.

To prove that each component is truly independent, we can create an App component that renders three clocks:

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

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

Each Clock component separately sets its own timer and updates it.

6 Event Handling

The rules

React events are named in a camelCase rather than pure lowercase.

To use JSX syntax you need to pass in a function as an event handler, not a string.

For example, traditional HTML:

<button onclick="activateLasers()">
  Activate Lasers
</button>
Copy the code

React is slightly different:

<button onClick={activateLasers}>  Activate Lasers
</button>
Copy the code

Another difference in React is that you can’t prevent default behavior by returning false. You must explicitly use preventDefault. For example, in traditional HTML blocking links opens a new page by default, you could write:

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

In React, it might look like this:

function ActionLink() {
  function handleClick(e) {    e.preventDefault();    console.log('The link was clicked.');  }
  return (
    <a href="#" onClick={handleClick}>      Click me
    </a>
  );
}
Copy the code

In this case, e is a composite event. React defines these composite events according to the W3C specification, so you don’t need to worry about cross-browser compatibility. React events are not exactly the same as native events

With React, you generally don’t need to use addEventListener to add listeners to created DOM elements. In fact, you only need to add listeners when the element is initially rendered.

When you define a component using ES6 class syntax, it is common practice to declare event handlers as methods in the class

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    HandleClick = this.handleclick.bind (this); handleClick = this.handleclick.bind (this); }

  handleClick() {    this.setState(state= > ({      isToggleOn: !state.isToggleOn    }));  }
  render() {
    return (
      <button onClick={this.handleClick}>        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

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

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. HandleClick = this.handleclick.bind (this); handleClick = this.handleclick.bind (this);

If you find using bind a hassle, there are two ways to get around it

Using the experimental public Class Fields syntax, you can bind callback functions correctly using class Fields

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

Create React App enables this syntax by default.

If you are not using the class fields syntax, you can use the arrow function in the callback:

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

The problem with this syntax is that a different callback is created each time LoggingButton is rendered. 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.

** Passes the argument ** to the event handler

In a loop, we usually pass extra arguments to the event handler. For example, 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.

Conditions apply colours to a drawing

React conditional rendering, like JavaScript, uses the JavaScript operator if or conditional operators to create elements that represent the current state, and then has React update the UI based on them.

Conditional render 1 if

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {    return <UserGreeting />;  }  return <GuestGreeting />; } ReactDOM.render(// Try changing to isLoggedIn={true}:
  <Greeting isLoggedIn={false} />.document.getElementById('root'));
Copy the code

The ** and operator && **

This is possible because 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 return value of the Render method is

0

render() {
  const count = 0;  return (
    <div>
      { count && <h1>Messages: {count}</h1>}    </div>
  );
}
Copy the code

Ternary operator

Another way to inline conditional rendering is to use the condition? Operator in JavaScript. True, false.

render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    <div>
      {isLoggedIn        ? <LogoutButton onClick={this.handleLogoutClick} />
        : <LoginButton onClick={this.handleLoginClick} />      }
    </div>  );
}
Copy the code

Just as in JavaScript, you can choose a more readable code style depending on your team’s preferences. Note that if conditions become too complex, you should consider how to extract components.

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) {// Block component rendering by returning null
  
  return null;
  
  }
  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

List & Key

How to convert lists in Javascript.

As follows, we double each item in the array using the map() function, and then we get a new list double and print it:

const numbers = [1.2.3.4.5];
const doubled = numbers.map((number) = > number * 2);
console.log(doubled);
Copy the code

In React, the process of converting an array to a list of elements is similar.

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) = >    
  <li>{number}</li>  );  return (
    <ul>{listItems}</ul>  );
}

const numbers = [1.2.3.4.5];
ReactDOM.render(
  <NumberList numbers={numbers} />.document.getElementById('root'));Copy the code

When we run this code, we’ll see a warning that a key should be provided for list items, which means that when you create an element, you must include a special key property

Let’s assign a key attribute to each list element to address the warning above:

const listItems = numbers.map((number) = >
    <li key={number.toString()}>      {number}
    </li>
  );
Copy the code

key

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.

const numbers = [1.2.3.4.5];
const listItems = numbers.map((number) = >
  <li key={number.toString()}>    {number}
  </li>
);
Copy the code

An element’s key should ideally be a unique string that the element has in the list. In general, we use the id in the data as the element key:

const todoItems = todos.map((todo) = >
  <li key={todo.id}>    
  {todo.text}
  </li>
);
Copy the code

As a last resort, you can use the element index as the key when the element has no specified ID

const todoItems = todos.map((todo, index) = >
  // Only do this if items have no stable IDs  
  <li key={index}>    
  {todo.text}
  </li>
);
Copy the code

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.

Why is key required ????

By default, React iterates through lists of both children of a DOM node when recursing to them. When a difference occurs, a mutation is generated.

When new elements are added at the end of the child element list, the update overhead is low. Such as:

<ul>
  <li>first</li>
  <li>second</li>
</ul>

<ul>
  <li>first</li>
  <li>second</li>
  <li>third</li>
</ul>
Copy the code

React matches two

  • first
  • trees, then matches the second< li>second tree, and finally inserts the

  • third
  • tree of the third element.

    If you simply insert the new element into the table header, the update will be expensive. Such as:

    <ul>
      <li>Duke</li>
      <li>Villanova</li>
    </ul>
    
    <ul>
      <li>Connecticut</li>
      <li>Duke</li>
      <li>Villanova</li>
    </ul>
    Copy the code

    React does not realize that it should keep

  • Duke
  • and

  • Villanova
  • , but instead rebuilds each child element. This situation can cause performance problems.

    Keys

    React introduced the key property to address these issues. When a child element has a key, React uses the key to match the child element of the original tree with the child element of the latest tree. The following example improves tree conversion efficiency with the addition of keys:

    <ul>
      <li key="2015">Duke</li>
      <li key="2016">Villanova</li>
    </ul>
    
    <ul>
      <li key="2014">Connecticut</li>
      <li key="2015">Duke</li>
      <li key="2016">Villanova</li>
    </ul>
    Copy the code

    React now knows that only elements with the ‘2014’ key are new; elements with the ‘2015’ and ‘2016’ keys are simply moved.

    In real development, it is not difficult to write a key. The element you want to present may already have a unique ID, so the key can be extracted directly from your data:

    <li key={item.id}>{item.name}</li>
    Copy the code

    When this is not the case, you can add an ID field to your model, or generate a key using a portion of the content as a hash. This key doesn’t need to be globally unique, but it needs to be unique in the list.

    Finally, you can also use the element’s index in the array as a key. This strategy is appropriate when elements are not reordered, and diff will slow down if the order changes.

    Component state may encounter some problems when subscription-based components are reordered. Because component instances decide whether to update and reuse based on their key, if the key is a subscript, the order in which changes are made changes the current key, causing states of uncontrolled components (such as input fields) to tamper with each other and change unpredictably.

    The correct way to use keys

    function ListItem(props) {
      / / right! Return 
  • {props. Value}
  • ; }
    function NumberList(props) { const numbers = props.numbers; const listItems = numbers.map((number) = > / / right! Key should be specified in the context of an array ); 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

    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

    The key will pass information to React, but not to your components. If you need the value of the key attribute in your component, pass it explicitly with another attribute name:

    const content = posts.map((post) = >
      <Post
        key={post.id}    
        id={post.id}    
        title={post.title} />
    );
    Copy the code

    In the example above, the Post component can read props. Id, but not props. Key.

    JSX allows any expression to be embedded in braces, so we can inline the result returned by map() :

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

    Sometimes this can make your code clearer, 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

    The form

    State of ascension

    Often, multiple components need to reflect the same changing data, and we recommend promoting the shared state to the nearest common parent. Let’s see how it works.

    So far, both TemperatureInput components have kept their data independently of each other in their own internal states.

    class TemperatureInput extends React.Component {
      constructor(props) {
        super(props);
        this.handleChange = this.handleChange.bind(this);
        this.state = {temperature: ' '};  }
    
      handleChange(e) {
        this.setState({temperature: e.target.value});  }
    
      render() {
        const temperature = this.state.temperature;    // ...  
    Copy the code

    However, we want the values in the two input boxes to be synchronized with each other. When we update the value in the Celsius input box, the Fahrenheit input box should display the converted Fahrenheit temperature and vice versa.

    In React, shared state is achieved by moving the states that need to be shared between multiple components up to their nearest common parent. This is known as a “state boost.” Next, we move state from the TemperatureInput component into the Calculator component.

    ** If the Calculator component has a shared state, it becomes the “data source” for the current temperature in the two temperature input boxes. It keeps the values of the two temperature input boxes consistent with each other. Since the props for both TemperatureInput components come from a common parent component Calculator, the content in the two input boxes will always be the same. 支那

    class Calculator extends React.Component {
      constructor(props) {
        super(props);
        this.handleCelsiusChange = this.handleCelsiusChange.bind(this);
        this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this);
        this.state = {temperature: ' '.scale: 'c'};  }
    
      handleCelsiusChange(temperature) {
        this.setState({scale: 'c', temperature});  }
    
      handleFahrenheitChange(temperature) {
        this.setState({scale: 'f', temperature});  }
    
      render() {
        const scale = this.state.scale;    const temperature = this.state.temperature;    const celsius = scale === 'f' ? tryConvert(temperature, toCelsius) : temperature;    const fahrenheit = scale === 'c' ? tryConvert(temperature, toFahrenheit) : temperature;
        return (
          <div>
            <TemperatureInput
              scale="c"
              temperature={celsius}          onTemperatureChange={this.handleCelsiusChange} />        <TemperatureInput
              scale="f"
              temperature={fahrenheit}          onTemperatureChange={this.handleFahrenheitChange} />        <BoilingVerdict
              celsius={parseFloat(celsius)} />      </div>); }}class TemperatureInput extends React.Component {
      constructor(props) {
        super(props);
        this.handleChange = this.handleChange.bind(this);
      }
    
      handleChange(e) {
        this.props.onTemperatureChange(e.target.value);  }
    
      render() {
        const temperature = this.props.temperature;    const scale = this.props.scale;
        return (
          <fieldset>
            <legend>Enter temperature in {scaleNames[scale]}:</legend>
            <input value={temperature}
                   onChange={this.handleChange} />
          </fieldset>); }}Copy the code

    Let’s take a look at what happens when you edit the content of the input field:

    React calls the onChange method in the DOM. In this example, it is the handleChange method of the TemperatureInput component.

    TemperatureInput components of handleChange method will be called this. Props. OnTemperatureChange (), and introduced to new input value as a parameter. Its props, such as onTemperatureChange, are provided by the parent component Calculator.

    The onTemperatureChange method in the child component TemperatureInput used in the Centigrade input is the same as the handleCelsiusChange method in the Calculator component when initially rendered, The onTemperatureChange method in the child component TemperatureInput used for the Fahrenheit input is the same as the handleFahrenheitChange method in the Calculator component. Therefore, whichever input box is edited calls the corresponding method in the Calculator component.

    Within these methods, the Calculator component calls this.setstate () with the new input value corresponding to the temperature unit of the current input field to request React to re-render itself.

    React calls the Render method of the Calculator component to get the UI rendering of the component. The temperature conversion takes place at this point, and the values in the two input boxes are recalculated from the current input temperature and its units of measurement.

    React uses the new props provided by the Calculator component to call the Render methods of the two TemperatureInput child components to obtain the UI rendering of the child components.

    React calls the Render method of the BoilingVerdict component and passes in the Celsius value as component props.

    The React DOM matches the input value to see if the water is boiling and updates the result to the DOM. The input box we just edited receives its current value, and the other input box is updated with the converted temperature value.

    Because each update goes through the same steps, the contents of the two input fields are always in sync.

    Study summary

    In React applications, any mutable data should have only one “data source” corresponding to it. Typically, state is added first to the component that needs to render the data. Then, if other components also need this state, you can promote it to the nearest common parent of those components. Instead of trying to synchronize state across different components, you should rely on top-down data flow.

    While promoting state requires more boilerplate code than bidirectional binding, it has the benefit of requiring less work to troubleshoot and isolate bugs. Because any state “exists” in a component, only the component itself can change it, the scope for finding bugs is greatly reduced. In addition, you can use custom logic to reject or convert user input.

    Composition vs inheritance

    To add

    The React philosophy

    To add