React中的props-drilling问题
在React中我们经常会碰到父组件一层一层的去给子组件传递props的问题, 这种一层一层的将props
往下传递的现象, 叫做props-drilling, drilling是下钻的意思, 生动的体现的这一现象
这个时候, 我们可以利用一些技巧来解决这些问题, 我们来看一个常见的场景
一. prop drilling 问题
合理使用 Component Composition
我们 authenticated-app 使用状态提升定义了一个公共的 prop, 并把它层层传递给了子组件
1.1 props-drilling的缺点
- 缺点一: state definition is far away the place where the state is being used 高耦合
- 缺点二: 我们这里使用状态提升定义了一个公共的 prop, 并把它层层传递给了子组件,(下钻)
Component Composition 把公共的 JSX.Element 当作变量传递给了子组件
- 可以将
state和子组件解耦合,子组件不再依赖父组件中传入的更改state的函数 - 无需在
interface层层更改state定义
Component Composition 实际上也是一种状态提升的手段,并不是适合每个场景,因为这样可能会让父组件变得更加复杂
这种对组件的控制反转减少了应用中传递的 props 数量,使代码更加干净,对根组件把控更深,特别是当我们使用 Ts 来进行类型控制的时候,中间传递者再也不需要考虑 props 如何消费,只负责传递即可
那么我们来看看什么是控制反转
二. 什么是控制反转
我们经常会使用控制反转的技巧来进行代码解耦合
那么什么是控制反转呢, 我们来看看这样一个场景
2.1 场景
如果我们有个 car 类, 需要使用到 engine(引擎)和 tires(轮胎)
import engine from "engine";
import tires from "tires";
class Car {
constructor() {
this.engine = new engine();
this.tires = tires.getInstance();
}
}
可以看到,engine 是通过 new 创建实例的,而 tires 是通过工厂模式的 getInstance 获取实例的,这样会有什么坏处呢
car 与 engine 和 tires 获取实例的方法高度耦合,倘如我们更改了 tires 获取实例的办法,那么需要找到使用了 tires 的地方全部进行修改
2.2 优化
此时我们可以定义一个容器
import engine from "engine";
import tires from "tires";
import Container from "contanier";
// 充当中间人
const container = new Container();
container.bind("engine", engine);
container.bind("tires", tires);
class Car {
constructor() {
// 只需关注中间人传过来的值即可
this.engine = container.get("engine");
this.tires = container.get("tires");
}
}
这样我们就利用 container 实现了解耦合
其实上面的 Component Composition 也是控制反转的一种设计模式