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>
<AddCounter
addClick={(count) => {
this.changeCounter(count);
}}
/>
<SubCounter
subClick={(count) => {
this.changeCounter(count);
}}
/>
</div>
);
}
}
export default Main;