软件设计原则
-
“开放封闭原则”
对拓展开放,对修改封闭 -
“单一职责”原则
单一职责原则又叫“单一功能原则”,它指的是一个类或者模块应该有且只有一个改变的原因。通俗来讲,就是说咱们的组件功能要尽可能地聚合,不要试图让一个组件做太多的事情。
高阶组件(HOC):最经典的组件逻辑复用方式
高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧。HOC 自身不是 React API 的一部分,它是一种基于 React 的组合特性而形成的设计模式。——React 官方
高阶组件的使用姿势是用“函数”包裹“组件”
栗子
// 假设 checkUserAccess 已经在 utils 文件中被封装为了一段独立的逻辑
import checkUserAccess from './utils
// 用高阶组件包裹目标组件
const withCheckAccess = (WrappedComponent) => {
// 这部分是通用的逻辑:判断用户身份是否合法
const isAccessible = checkUserAccess()
// 将 isAccessible(是否合法) 这个信息传递给目标组件
const targetComponent = (props) => (
<div className="wrapper-container">
<WrappedComponent {...props} isAccessible={isAccessible} />
</div>
);
return targetComponent;
};
/* 使用 */
const EnhancedAComponent = withCheckAccess(Acomponent);
Render Props:逻辑复用的另一种思路
术语“render prop”是指一种在 React 组件之间使用一个值为函数的 prop 共享代码的简单技术。——React 官方
render props强调的是用“组件”包裹“函数”
- render props 的载体应该是一个React 组件,这一点是与高阶组件不同的(高阶组件本质是函数);
- render props 组件正常工作的前提是它的子组件需要以函数形式存在。
栗子
// 假设 checkUserAccess 已经在 utils 文件中被封装为了一段独立的逻辑
import checkUserAccess from './utils
// 定义 render props 组件
const CheckAccess = (props) => {
// 这部分是通用的逻辑:判断用户身份是否合法
const isAccessible = checkUserAccess()
// 将 isAccessible(是否合法) 这个信息传递给目标组件
return <React.Fragment>
{props.children({ ...props, isAccessible })}
</React.Fragment>
};
/* 使用 */
<CheckAccess>
{
(props) => {
const { isAccessible } = props;
return <ChildComponent {...props} isAccessible={isAccessible} />
}
}
</CheckAccess>
函数并不一定要作为子组件传入,它也可以以任意属性名传入,只要 render props 组件可以感知到它就行
// 假设 checkUserAccess 已经在 utils 文件中被封装为了一段独立的逻辑
import checkUserAccess from './utils
// 定义 render props 组件
const CheckAccess = (props) => {
// 这部分是通用的逻辑:判断用户身份是否合法
const isAccessible = checkUserAccess()
// 将 isAccessible(是否合法) 这个信息传递给目标组件
return <React.Fragment>
{props.checkTaget({ ...props, isAccessible })}
</React.Fragment>
};
/* 使用 */
<CheckAccess
checkTaget={(props) => {
const { isAccessible } = props;
return <ChildComponent {...props} isAccessible={isAccessible} />
}}
/>
render props 和高阶组件 的区别
- 对数据的处理上:在高阶组件中,目标组件对于数据的获取没有主动权,数据的分发逻辑全部收敛在高阶组件的内部;而在 render props 中,除了父组件可以对数据进行分发处理之外,子组件也可以选择性地对数据进行接收
- 使用层面:高阶组件的使用姿势是用“函数”包裹“组件”,而 render props 恰恰相反,它强调的是用“组件”包裹“函数”
自定义Hook:设计模式解决不了所有的问题
想要去复用一段逻辑时,第一反应肯定不是“高阶函数”或者“render props”,而应该是“自定义 Hook”。Hooks 能够很好地规避掉旧时类组件中各种设计模式带来的弊端,比如说它不存在嵌套地狱,允许属性重命名、允许我们在任何需要它的地方引入并访问目标状态等