React 基础巩固(十八)——组件化开发(二)
生命周期
-
生命周期是一个抽象的概念,在生命周期的整个过程中,分成了很多个阶段
- 比如装载阶段(
Mount
),组件第一次在 DOM 树中被渲染的过程 - 比如更新过程(
Update
),组件状态发生变化,重新更新渲染的过程 - 比如卸载过程(
Unmount
),组件从 DOM 树中被移除的过程
- 比如装载阶段(
-
React 内部为了告诉我们当前处于什么阶段,对我们组件内部实现的某些函数进行回调,这些函数就是生命周期函数
- 比如实现 componentDidMount 函数:组件已经挂载到 DOM 上时,就会回调;
- 比如实现 componentDidUpdate 函数:组件已经发生了更新时,就会回调;
- 比如实现 componentWillUnmount 函数:组件即将被移除时,就会回调;
-
React 生命周期主要指类的生命周期,函数式组件是没有生命周期函数的(可通过 hooks 模拟生命周期回调)
-
生命周期解析
-
生命周期函数
componentDidMount
- componentDidMount()会在组件挂载后(插入 DOM 树中)立即调用
- 通常,依赖于 DOM 的操作、发送网络请求(官方建议)、添加订阅等操作可以在这里进行
componentDidUpdate
- componentDidMount()会在更新后被立即调用,首次渲染不会执行此方法
- 当组件更新后,可以在此处对 DOM 进行操作
- 若对更新前后的 props 进行了比较,也可以选择在此处进行网络请求
componentWillUnmount
- componentWillUnmount()会在组件卸载及销毁之前直接调用
- 在此方法中执行必要的清理操作(清除 timer、取消网络请求、清除订阅等)
shouldComponentUpdate
- 用于判定是否更新组件
getDerivedStateFromProps
- state 的值在任何时候都依赖于 props 时使用;
- 该方法返回一个对象来更新 state
getSnapshotBeforeUpdate
- 在 React 更新 DOM 之前回调的一个函数,可以获取 DOM 更新前的一些信息(比如说滚动位置)
组件嵌套
- 对组件进行拆分,拆分成一个个小的组件
- 将这些组件嵌套在一起,最终形成应用
组件通信
- 父组件通过
属性 = 值
的形式传递数据给子组件 - 子组件通过
props
参数获取父组件传递过来的数据
父传子(Main -> MainBanner)
- Main.jsx
import React, { Component } from "react";
import MainBanner from "./MainBanner";
import MainProductList from "./MainProductList";export class Main extends Component {constructor() {super();this.state = {banners: ["test1", "test2", "test3"],productList: ["pro1", "pro2", "pro3"],};}render() {const { banners, productList } = this.state;return (<div className="main"><div>main</div><MainBanner banners={banners} /><MainProductList productList={productList} /></div>);}
}export default Main;
- MainBanner.jsx
import React, { Component } from "react";export class MainBanner extends Component {// 默认值新写法// static defaultProps = {// banners: ['default'],// }render() {const { banners } = this.props;return (<div><ul>{banners.map((item) => {return <li key={item}>{item}</li>;})}</ul></div>);}
}// 类型验证
MainBanner.protoTypes = {banners: PropTypes.array.isRequired,title: PropTypes.string,
};// 默认值
MainBanner.defaultProps = {banners: ["default"],
};export default MainBanner;
子传父(AddCounter -> Main)
- AddCounter.jsx
import React, { Component } from "react";export class AddCounter extends Component {addCount(num) {console.log(num);this.props.addClick(num);}render() {return (<div><button onClick={(e) => this.addCount(1)}>+1</button><button onClick={(e) => this.addCount(5)}>+5</button><button onClick={(e) => this.addCount(10)}>+10</button></div>);}
}export default AddCounter;
- Main.jsx
import React, { Component } from "react";
import AddCounter from "./AddCounter";
import SubCounter from "./SubCounter";
export class Main extends Component {constructor() {super();this.state = { counter: 100 };}changeCounter(count) {this.setState({ counter: this.state.counter + count });}render() {const { counter } = this.state;return (<div className="main"><div>当前计数:{counter}</div><AddCounteraddClick={(count) => {this.changeCounter(count);}}/><SubCountersubClick={(count) => {this.changeCounter(count);}}/></div>);}
}
export default Main;