React js教程:React 中的片段和纯组件(12)

作者 : 慕源网 本文共5957个字,预计阅读时间需要15分钟 发布时间: 2021-10-27 共210人阅读

本文是React 教程系列的一部分。您可以在此处找到本系列之前所有帖子的链接

介绍

上一篇文章中,我们了解了 React 生命周期的组件以及它是如何在 React 中使用的。在本文中,我们将了解 Fragment 和 Pure Component 及其在 React 中的重要性。

Fragments

在 React 中,当在 render() 方法中返回任何元素时,必须将多个元素包装在主容器中。为了减轻添加容器以添加多个元素的麻烦,引入了 Fragment 的概念。在 <React.Fragment> 内部,不需要添加任何父容器。

Fragment 的概念是在 React v16 之后引入的,所以要使用 Fragment 的概念,你的应用程序必须更新到 React 16.2 版本让我们看一个有多个元素的代码。

例如,下面的代码有多个元素。

import React,{Component} from '.react';  
  
class Fragments extends Component{  
        render(){  
                return(  
                        <p>Test</p>  
                        <p>Test 1</p>  
                        <p>Test 2</p>  
                )  
        }         
}  

下面,它将显示错误,因为 JSX 必须有 1 个父元素。

React js教程:React 中的片段和纯组件(12)

现在,让我们看看第二种方法,即在每个元素后添加一个逗号 (,)。
import React,{Component} from '.react';  
  
class Fragments extends Component{  
       render(){  
              return(  
                     <p>Test</p>,  
                     <p>Test 1</p>,  
                     <p>Test 2</p>  
              )  
       }  
}  

输出将显示如下。

React js教程:React 中的片段和纯组件(12)

如您所见,所有三个元素中仅显示最后一个元素。如果我们想在浏览器中显示所有 3 个元素,那么我们需要使用方括号 [] 而不是括号 () 返回数组,如下所示。
import React,{Component} from 'react';  
class Fragments extends Component{  
        render(){  
                return[  
                        <p>Test</p>,  
                        <p>Test 1</p>,  
                        <p>Test 2</p>  
                ]  
        }  
}  
  
export default Fragments;  

现在,输出将显示如下。

React js教程:React 中的片段和纯组件(12)

这种方法也用于返回数组,但这是一种非 JSX 语法。所以,让我们转向 Fragment,这是一个 React 概念。
import React,{Component,Fragment} from 'react';  
class Fragments extends Component{  
       render(){  
              return(  
                     <Fragment>  
                            <p>Test</p>  
                            <p>Test 1</p>  
                            <p>Test 2</p>  
                     </Fragment>  
              )  
       }  
}  
  
export default Fragments;  

输出将显示如下。

React js教程:React 中的片段和纯组件(12)

使用片段呈现元素数组的第二种语法是使用 <></>,
import React,{Component} from 'react';  
  
class Fragments extends Component{  
        render(){  
                return(  
                        <>  
                                <p>Test</p>  
                                <p>Test 1</p>  
                                <p>Test 2</p>  
                        </>  
               )  
        }  
}  
  
export default Fragments;  

输出将显示与上面相同。

React js教程:React 中的片段和纯组件(12)

虽然使用 React.Fragment 不会向 DOM 添加任何 HTMLElement,但 React.Fragment 节点是作为父标记添加到 JSX 元素的,而不会向 DOM 添加任何额外元素。

片段(Fragments)的好处

  1. 一些css机制,比如CSS Grid、Flexbox,有一些特殊的父子关系,在中间添加div使得在提取逻辑组件的同时很难保持想要的布局。
  2. 这提供了更快且使用更少的内存,因为它不会创建任何额外的节点。当应用程序非常大并且使用这些片段可以防止创建不必要的元素时,这会带来好处。
  3. 改进了 JSX 的语义标记。如果需要,可以使用包装器的元素,而不是因为它们是强制的。
  4. 它提供了更高的渲染性能和更少的内存开销。

片段(Fragments)的使用

返回元素组

在这里,片段可用于返回元素列表,而无需将它们包装在容器或数组中。这在返回表单和文本标记时很有用,因为将它们包装在 div 中可能会导致应用样式时出现问题。

根据下面的代码,我们定义了输入文本和按钮。

import React,{Component,Fragment} from 'react';  
  
class Fragments extends Component{  
        constructor(props){  
        super(props);  
                this.state={  
                        UserName : ''  
                }  
        }  
  
        render(){  
                return(  
                        <Fragment>  
                                <label>Name : </label>   
                                <input type='text' name='txtuser' id='textuser' value={this.UserName}/>  
                                <button> Click Me !</button>  
                        </Fragment>  
                )  
        }  
}  
  
export default Fragments;  

输出显示如下。

React js教程:React 中的片段和纯组件(12)

有条件地渲染元素组

片段允许有条件地呈现元素,而无需添加额外的标记标签。我们可以在 Fragment 中使用三元或 case 语句在浏览器中显示输出。让我们看看下面的例子。

import React,{Component,Fragment} from 'react';  
  
const info = {  
        color: 'blue',  
        fontWeight: 'bold',  
        padding: '4px'  
}  
  
const error = {  
        color: 'red',  
        fontWeight: 'bold',  
        padding: '4px'  
}  
  
class Fragments extends Component{  
        constructor(props){  
                super(props);  
                this.state={   
                        UserName : "",  
                        isClicked : false  
                }  
                this.handleSubmit = this.handleSubmit.bind(this);  
                this.handleInput = this.handleInput.bind(this);  
        }  
  
        handleSubmit(){  
                this.setState({  
                        isClicked :true  
                });  
        }  
  
        handleInput(e){  
                this.setState({  
                        UserName: e.target.value  
                })  
        }  
  
        render(){   
                return(  
                        <Fragment>  
                                <label>Name : </label>   
                                <input type='text' name='txtuser' id='textuser' value={this.state.UserName} onChange={this.handleInput}/>  
                                <button onClick={this.handleSubmit}> Click Me !</button><br/>  
                                {this.state.isClicked ? (   
                                        <p style={info}>You clicked button, your name is <b>{this.state.UserName}</b></p>   
                                ):(   
                                        <p style={error}>Please Click button</p>   
)}   
                       </Fragment>  
                )  
        }  
}  
  
export default Fragments;  

输出将显示如下。

React js教程:React 中的片段和纯组件(12)

React js教程:React 中的片段和纯组件(12)

带数组的片段

React 提供了 Fragments 概念来代替数组。

使用 Fragment 有以下好处,

  • 使用数组时,子元素必须用逗号分隔 – 片段不存在相同的情况。
  • 一个数组需要一个key来防止React key;片段不存在相同的情况。
  • 在 Array 中,字符串必须用双引号引起来,而在片段中它不包含这样的引号

例如,要定义数组,我们有以下代码。

return[  
      "This is my React Application.",  
      <h2 key="heading-1">Include Introduction</h2>,  
      "Now moving towards.",  
      <h2 key="heading-2">The Complex chapters </h2>,  
      "And provide practical session."  
];  
 现在,更新 Fragments 的代码如下。
render(){   
     return(  
          <Fragment>  
               This is my React Application  
               <h2>Include Introduction</h2>  
               Now moving towards  
               <h2>The Complex chapters </h2>  
               And provide practical session  
           </Fragment>  
       );  
}  

纯组件

在 React 中,只有当组件为相同的 state 和 props 呈现相同的输出并且其返回值对于相同的输入值始终相同时,才被声明为纯组件。Component extends React.PureComponent 基类被视为纯组件。

Pure Component 包括一些性能改进和渲染优化,因为 React 实现了 shouldComponentUpdate() 方法来对 props 和 state 进行浅层比较。

纯组件的 shouldComponentUpdate() 方法只是浅层比较对象。在使用复杂数据结构的情况下,它可以为更深层次的差异生成假阴性。当您拥有简单的道具和状态或使用 forceUpdate() 时,您可以使用这种方法,或者您可以使用不可变对象,以防进行深入的数据比较。

当 PureComponent 使用 shouldComponentUpdate() 方法时,它会跳过整个组件子树的 props 更新。因此,在使用它时,请确保所有孩子都是纯洁的。

例如,在 React.Component 的情况下

import React from 'react';  
  
class Calculation extends React.Component{  
        constructor(props){  
                super(props);  
                this.state={  
                        firstName : "",  
                        fullName:""  
                }  
                this.handleFirstName = this.handleFirstName.bind(this);   
                this.handleClick = this.handleClick.bind(this);  
        }  
  
        handleFirstName(e){  
                this.setState({  
                        firstName : e.target.value  
                });   
        }  
  
        handleClick(e){  
                this.setState({  
                        fullName : this.state.firstName  
                });  
        }  
  
        render(){  
                console.log('rendered' + this.state.fullName);  
                return(  
                        <div>  
                                <input type="text" value={this.state.firstName} placeholder="First Name" onChange={this.handleFirstName}></input>   
                                <button onClick={this.handleClick}>Click Me!</button>  
                                <p> {this.state.fullName}</p>  
                        </div>  
                )  
        }  
}  
  
export default Calculation;  

输出将显示如下。

React js教程:React 中的片段和纯组件(12)

每次单击按钮时,控制台中的上述输出都会调用 render 方法,即使文本框中没有进行任何更改。

现在,将 React.Component 更新为 React.PureComponent

import React from 'react';  
  
class Calculation extends React.PureComponent{  
       constructor(props){  
              super(props);  
              this.state={  
                     firstName : "",  
                     fullName:""  
              }  
              this.handleFirstName = this.handleFirstName.bind(this);   
              this.handleClick = this.handleClick.bind(this);  
       }  
  
       handleFirstName(e){  
              this.setState({  
                     firstName : e.target.value  
              });   
       }  
  
       handleClick(e){  
              this.setState({  
                     fullName : this.state.firstName  
              });  
       }  
  
       render(){  
              console.log('rendered' + this.state.fullName);  
              return(  
                     <div>  
                            <input type="text" value={this.state.firstName} placeholder="First Name" onChange={this.handleFirstName}></input>   
                            <button onClick={this.handleClick}>Click Me!</button>  
                            <p> {this.state.fullName}</p>  
                     </div>  
              )  
       }  
}  
  
export default Calculation; 

现在,观察下面的输出。

React js教程:React 中的片段和纯组件(12)

现在查看控制台,如果文本框中没有更改,则不会每次都调用按钮渲染方法。

浅比较

在使用纯组件时,术语浅比较很重要。浅比较是指 2 种原始类型,原始类型和复杂类型,

原始类型

例如,在原始类型中,我们有 2 个值,a 和 b 任何类型,如字符串、布尔值或数字。如果两者属于相同类型且具有相同值,则浅比较 b 返回 true

例子,

let a = “Test”;  
let b = “Test”;  
console.log(a===b); // return true;  

复杂类型

在像数组和对象这样的复杂类型中,如果两者具有相同的对象,则浅比较 b 返回 true

例子,

let a = {1,2,3}  
let b = {1,2,3}  
let c = a  
console.log(a===b); // return false; point to different object  
console.log(a===c); // return true, as it points to the same object 

使用纯组件时要记住的要点:

  • 如果父类扩展 PureComponent,那么我们必须确保子类也是纯的,以避免意外行为。
  • 永远记住永远不要改变状态,状态总是返回一个反映新状态的新对象。
  • 如果 props 和 state 没有变化,Pure Component 将不会被重新渲染。
  • 纯组件应该用于小型应用程序。

概括

在本文中,我们了解了 Fragment 和 Pure Component 及其在 React 中的使用。此外,我们回顾了浅比较的概念。在下一篇文章中,我们将了解 memo 是一个功能组件,以及它与纯组件的区别。以及 React 中 Refs 的概念。

本系列的下一个 >>React 中的门户和错误边界


慕源网 » React js教程:React 中的片段和纯组件(12)

常见问题FAQ

程序仅供学习研究,请勿用于非法用途,不得违反国家法律,否则后果自负,一切法律责任与本站无关。
请仔细阅读以上条款再购买,拍下即代表同意条款并遵守约定,谢谢大家支持理解!

发表评论

开通VIP 享更多特权,建议使用QQ登录