React - 组件优化、children props 与 render props、错误边界

张开发
2026/4/9 19:38:44 15 分钟阅读

分享文章

React - 组件优化、children props 与 render props、错误边界
一、组件优化1、问题引入1基本介绍只要执行 setState即使不改变状态数据, 组件也会重新 render只要当前组件重新 render就会自动重新 render 子组件纵使子组件没有用到父组件的任何数据只要父组件更新不管子组件的 props 变没变子组件都会重新渲染2演示import { Component } from react; import Child from ../Child; import ./index.css; export class Parent extends Component { state { username: tom, age: 18 }; change () { this.setState({ username: this.state.username, age: this.state.age }); }; render() { console.log(Parent 渲染了); const { username, age } this.state; return ( div classNameparent h3Parent/h3 divusername: {username}/div divage: {age}/div button onClick{this.change}点我修改/button Child / /div ); } }.parent{width:500px;background-color:orange;padding:8px;}import { Component } from react; import ./index.css; export default class Child extends Component { render() { console.log(Child 渲染了); return ( div classNamechild h3Child/h3 /div ); } }.child{width:100%;background-color:skyblue;padding:8px;}首次渲染输出结果如下Parent 渲染了 Child 渲染了第 1 次点击【点我修改】按钮输出结果如下Parent 渲染了 Child 渲染了第 2 次点击【点我修改】按钮输出结果如下Parent 渲染了 Child 渲染了2、问题原因Component 中的 shouldComponentUpdate 方法总是返回 true3、处理策略重写 shouldComponentUpdate 方法比较新旧 state 或 props 数据如果有变化则返回 true没有则返回 falseimport { Component } from react; import Child from ../Child; import ./index.css; export class Parent extends Component { state { username: tom, age: 18 }; change () { this.setState({ username: this.state.username }); }; shouldComponentUpdate(nextProps, nextState) { // nextProps 是接下来要变化的目标 props // nextState 是接下来要变化的目标 state return nextState.username ! this.state.username || nextState.age ! this.state.age; } render() { console.log(Parent 渲染了); const { username, age } this.state; return ( div classNameparent h3Parent/h3 divusername: {username}/div divage: {age}/div button onClick{this.change}点我修改/button Child / /div ); } }使用 PureComponent它重写了 shouldComponentUpdate 方法只有 state 或 props 数据有变化才返回 trueimport { PureComponent } from react; import Child from ../Child; import ./index.css; export class Parent extends PureComponent { state { username: tom, age: 18 }; change () { this.setState({ username: this.state.username }); }; render() { console.log(Parent 渲染了); const { username, age } this.state; return ( div classNameparent h3Parent/h3 divusername: {username}/div divage: {age}/div button onClick{this.change}点我修改/button Child / /div ); } }4、注意事项1基本介绍PureComponent 只是进行 state 和 props 数据的浅比较如果是数据对象内部数据变了返回 false不要直接修改 state 数据而是要产生新数据2演示import { PureComponent } from react; import Child from ../Child; import ./index.css; export class Parent extends PureComponent { state { person: { username: tom, age: 18, }, }; // 这里改变了第 1 层 change1 () { this.setState({ person: { ...this.state.person } }); }; // 这里改变了第 2 层没有改变第 1 层 change2 () { const { person } this.state; person.username jerry; person.age 20; this.setState({ person: person }); }; render() { console.log(Parent 渲染了); const { username, age } this.state.person; return ( div classNameparent h3Parent/h3 divusername: {username}/div divage: {age}/div button onClick{this.change1}点我修改 1/button button onClick{this.change2}点我修改 2/button Child / /div ); } }.parent{width:500px;background-color:orange;padding:8px;}import { Component } from react; import ./index.css; export default class Child extends Component { render() { console.log(Child 渲染了); return ( div classNamechild h3Child/h3 /div ); } }.child{width:100%;background-color:skyblue;padding:8px;}首次渲染输出结果如下Parent 渲染了 Child 渲染了第 1 次点击【点我修改 1】按钮输出结果如下Parent 渲染了 Child 渲染了第 2 次点击【点我修改 2】按钮输出结果如下Parent 渲染了 Child 渲染了第 1 次点击【点我修改 2】按钮输出结果如下无第 2 次点击【点我修改 2】按钮输出结果如下无二、children props 与 render props1、基本介绍children props 是通过组件标签体的方式向组件内部传递内容在组件内部可以通过props.children来获取这些内容但是如果内容需要父组件内部的数据children props 做不到需要使用 render props 来实现2、演示1children propsexport default function Card(props) { return ( h3Card/h3 {props.children} / ); }import Card from ./components/Card; export default function App() { return ( Card p这是卡片内部的内容/p button点击按钮/button /Card / ); }2render propsimport { useState } from react; export default function Card(props) { const [content] useState(这是一段测试内容); return ( h3Card/h3 {props.render(content)} / ); }export default function CardInner(props) { return ( p这是卡片内部的内容/p button点击按钮/button div{props.content}/div / ); }import Card from ./components/Card; import CardInner from ./components/CardInner; export default function App() { return ( Card render{(content) CardInner content{content} /} / / ); }三、错误边界1、基本介绍错误边界Error Boundary用来捕获后代组件错误渲染出备用页面只能捕获后代组件生命周期产生的错误不能捕获自己组件产生的错误以及其他组件在合成事件、定时器中产生的错误2、演示import { PureComponent } from react; import Child from ../Child; import ./index.css; export class Parent extends PureComponent { state { hasError: , }; static getDerivedStateFromError(error) { console.log(, error); return { hasError: error }; } componentDidCatch(error, info) { console.log(此处统计错误反馈给服务); console.log(error, info); } render() { return ( div classNameparent h3Parent/h3 {this.state.hasError ? h3当前网络不稳定稍后再试/h3 : Child /} /div ); } }.parent{width:500px;background-color:orange;padding:8px;}import { Component } from react; import ./index.css; export default class Child extends Component { // state { // users: [ // { id: 001, name: tom, age: 18 }, // { id: 002, name: jack, age: 19 }, // { id: 003, name: merry, age: 20 }, // ], // }; // 模拟一个错误 state { users: test, }; render() { return ( div classNamechild h3Child/h3 {this.state.users.map((userObj) { return ( div key{userObj.id} {userObj.name} ----- {userObj.age} /div ); })} /div ); } }.child{width:100%;background-color:skyblue;padding:8px;}

更多文章