持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第32天,点击查看活动详情
前言
今天是React知识点的最后一天。分别是PureComponent , RenderProps , ErrorBoundary。是一些比较高级的用法,今天就只简单的了解其中的作用,基本概念,不做深入了解,耗时耗力最后浪费时间不用就忘记了,在日常开发工作中很少用到,但是要知道有这些东西。
PureCompoment
首选复习一下在脚手架中定义一个组件的方法会使用extends关键字继承一个react中的组件:Compment,看下面的例子:
import React, { Component } from "react";
export default class Home extends Component{
render(){
return (
<div style={{ padding: 20 }}>
<h2>Home View</h2>
<p>在React中使用React Router v6 的指南</p>
</div>
)
}
}
PureComponent的用法跟这个Component一样的,PureComponent的作用就是,当组件更新渲染时,组件中 props 和 state 都没发生改变, render重新渲染的方法就不会触发,省去 虚拟DOM 的生成和比对的过程,起到了达到提升性能的目的。具体就是 PureComponent 自动帮我们做了一层浅比较。
做一下代码演示: App.js:
import React,{Component} from 'react';
import Home from './pages/Home';
export default class App extends Component {
state = {
data: []
}
componentDidMount() {
// 定时任务,每隔一秒更新数据
setInterval(() => {
this.setState({
title: 'react line 1'
})
}, 1000)
}
render() {
return(
<div>
<Home value={this.state.title} />
</div>
)
}
}
这个App.js会每个1秒钟设置state,但是设置的内容相同,接下来这里不会更改,里面的Home组件分别使用PureComponent和Component的区别
脚手架src/Home/index.js,使用Component:
import React,{Component} from 'react';
export default class Home extends Component {
render() {
console.log('render!!!')
return(
<div>{this.props.value}</div>
)
}
}
效果:
脚手架src/Home/index.js,使用PureComponent
import React,{PureComponent} from 'react';
export default class List extends PureComponent {
render() {
console.log('render!!!')
return(
<div>{this.props.value}</div>
)
}
}
效果:
总结:
使用了PureComponent查看到每次更新的state是一样的不会重复更新渲染子组件,Component会跟着父组件的定时任务一直进行更新,不对比更新的值是否相同。所以说对性能有一定的优化作用。
RenderProps
在组件中调用子组件组件时,引入一个函数类型的 prop,这个 prop定义了组件的渲染方式。是一种在组件间共享逻辑的技巧。使用RenderProps通过prop传递一些差异化配置让代码重用,这样说起来有点生硬,看代码: App.js
import React,{Component} from 'react';
import Home from './pages/Home';
export default class App extends Component {
render() {
return(
<div>
<Home render={(str)=>(
<div>
<h1>{str}</h1>
</div>
)} />
</div>
)
}
}
在App这个父组件调用Home组件时在render这个属性中传递一个函数,接下来子组件Home中使用这个匿名函数: src/pages/Home/index.js
import React,{Component} from 'react';
export default class List extends Component {
render() {
const { render} = this.props;
return(
<div>
{render('栓Q')}
</div>
)
}
}
效果:
这样在父组件中使用共用的功能函数,子组件实现自定义的功能。真是妙啊,这里的render 是一个自定义的属性,可以使其他的内容在父组件与子组件中一定要对应的上,例如这样(不然就会报错):
ErrorBoundary
这个单词的意思是错误边界的意思,在JavaScript中一般使用try-catch去捕捉代码的错误,但是在React的组件中要使用异常捕获,需要使用 Error Boundary 中 componentDidCatch 钩子函数来对页面异常进行捕获,从而不将异常扩散到整个页面,有效防止页面白屏。这里只做一个简单的代码实例了解:
App.js:
import React,{Component} from 'react';
import Home from './pages/Home'
import Index from './pages/Index'
export default class App extends Component {
render() {
return(
<div>
<Home >
<Index value={this.state.count} />
</Home>
</div>
)
}
}
Home/index.js:
import React from 'react';
export default class Home extends React.Component {
state = {
hasError: false
};
// 返回一个对象,更新state,用于渲染备用UI
static getDerivedStateFromError(error) {
console.log(error);
return { hasError: true };
};
// 获取错误日志,可用于上传服务器
componentDidCatch(error, errorInfo) {
console.log(error);
console.log(errorInfo);
};
render() {
const { hasError } = this.state;
const { children } = this.props;
if (hasError) {
return (
<div>
错误就是我
</div>
)
} else {
return children;
}
}
}
进行错误捕捉,显示默认页面 Index/index.js:
import React from 'react'
export default function Index() {
return (
<div>
<button onClick={()=>{ throw new Error("Error is three")}}>触发错误</button>
</div>
)
}
这里主动把组件名写错,让上级的组件捕获这个错误,注意ErrorBoundary 在开发模式不能体现出效果,这里就不展示了。主要重点是封装错误捕捉的组件
总结
到此为止React高级用法已总结完毕,今天学习的三个知识都做了最简单的例子,只做基本情况了解,其他的问题到开发中总结吧,React学习到此结束。