【React学习】React高级特性

1. 函数式组件和类组件区别

  • 函数式组件
    函数式组件是一种简单的组件定义方式,它是一个以JavaScript函数为基础的组件。
    可以把函数式组件理解为纯函数,它的输入为props,输出为JSX。函数式组件没有状态,也没有生命周期。
function List(props){
    
    
	const {
    
    list} = this.props

	return <ul>
			{
    
    
				list.map((item, index) => {
    
    
					return <li key={
    
    item.id}>
								<span>{
    
    item.title}</span>
						   </li>
				})
			}
		</ul>
}
  • 类组件
    类组件是React中的早期概念,它通过继承React.Component类来创建。类组件在React的生命周期和状态管理方面具有更多的控制权。
class List extends React.Component{
    
    
	constructor(props){
    
    
		super(props)
	}
	render(){
    
    
		const {
    
    list} = this.props

		return <ul>
			{
    
    
				list.map((item, index) => {
    
    
					return <li key={
    
    item.id}>
								<span>{
    
    item.title}</span>
						   </li>
				})
			}
		</ul>
	}
}

2. 非受控组件

非受控组件:通过在组件在传入ref属性,然后通过ref属性拿到当前组件的DOM节点,通过DOM节点拿到当前组件的值。通过这种方式拿到的组件的值,是不受组件的状态控制的。这种组件称为“非受控组件”。

  • 以下代码示例中,alert中的提示信息为input标签DOM元素中的值,而不是状态中的值。

在这里插入图片描述

class App extends React.Component{
    
    
    constructor(props) {
    
    
        super(props)
        this.state = {
    
    
            name: '小白',
        }
        this.nameInputRef = React.createRef() // 通过React.createRef()方法创建ref
    }
	
	alertName = () => {
    
    
        const elem = this.nameInputRef.current // 通过 ref 获取 DOM 节点
        alert(elem.value) // 不是state的值,而是从DOM元素中取得的值
    }

	render(){
    
    
		return(
			<div>
				<input defaultValue={
    
    this.state.name} ref={
    
    this.nameInputRef}/>
				<span>state.name: {
    
    this.state.name}</span>
				<br/>
				<button onClick={
    
    this.alertName}>alert name</button>
			</div>				
		)
	}
}
  • 非受控组件的使用场景:必须手动操作DOM元素,只更改组件的状态无法实现目的。例如文件上传,因为文件的相关信息必须通过DOM元素的files属性获取。

在这里插入图片描述

class App extends React.Component{
    
    
    constructor(props) {
    
    
        super(props)
        this.fileInputRef = React.createRef() // 通过React.createRef()方法创建ref
    }
	
	alertFile = () => {
    
    
        const elem = this.fileInputRef.current // 通过 ref 获取 DOM 节点
        alert(elem.files[0].name) // 打印上传的文件的名字
    }

	render(){
    
    
		return(
			<div>
				<input type="file" ref={
    
    this.fileInputRef}/>
				<button onClick={
    
    this.alertFile}>alert file</button>
			</div>				
		)
	}
}

3. Portals

React 中的 Portals(传送门)是一种高级特性,允许你将子组件渲染到父组件的 DOM 层次结构之外的位置,能够更灵活地管理组件的渲染位置。这对于在 React 应用程序中处理一些特殊的 UI 需求非常有用,例如在模态框、弹出窗口或全局组件中显示内容。

React 组件通常会将它们的输出渲染到它们的父组件的DOM中。但是使用 Portals,可以将子组件渲染到应用程序的DOM层次结构之外的位置。这使得你可以在应用程序的不同部分渲染内容,而不受父组件的约束。

通过 ReactDOM.createPortal() 方法实现Portals,该方法接受两个参数:1. 要渲染的React元素; 2. 目标DOM节点;

ReactDOM.createPortal(
  <ChildComponent />,
  document.getElementById('portal-root')
);

上述代码,将<ChildComponent/> 组件渲染到 id="portal-root"的DOM节点之外的位置。

4. context

5. 异步组件

在React框架中,当应用程序变得复杂时,通过使用异步加载组件的技术在需要时加载必要的组件,可以减少初始加载时间并提高应用程序性能。通常使用React.lazy()import()的组合来实现异步加载组件。

使用 React.lazy() 创建异步组件:使用 React.lazy() 函数来创建异步加载的组件。这个函数接受一个函数,这个函数返回一个动态 import() 调用的结果,该调用加载组件的模块。

const AsyncComponent = React.lazy(() => import('./AsyncComponent'));

异步加载组件需要时间,因此在组件加载期间,可以显示一个loading。使用 Suspense 组件来包装异步组件,在 Suspense 组件中设置 fallback 属性来定义加载过程中显示的内容。

import React, {
    
     Suspense } from 'react';

const AsyncComponent = React.lazy(() => import('./AsyncComponent'));

function App() {
    
    
  return (
    <div>
      <Suspense fallback={
    
    <div>Loading...</div>}>
        <AsyncComponent />
      </Suspense>
    </div>
  );
}

上述代码中,当AsyncComponent组件在加载时,会渲染Loading...元素。

6. 性能优化

7. 高阶组件HOC

8. render prop

猜你喜欢

转载自blog.csdn.net/zx1041561837/article/details/132611386