React设计模式

软件设计原则

  1. “开放封闭原则”
    对拓展开放,对修改封闭

  2. “单一职责”原则
    单一职责原则又叫“单一功能原则”,它指的是一个类或者模块应该有且只有一个改变的原因。通俗来讲,就是说咱们的组件功能要尽可能地聚合,不要试图让一个组件做太多的事情。

高阶组件(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强调的是用“组件”包裹“函数”

  1. render props 的载体应该是一个React 组件,这一点是与高阶组件不同的(高阶组件本质是函数);
  2. 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 和高阶组件 的区别

  1. 对数据的处理上:在高阶组件中,目标组件对于数据的获取没有主动权,数据的分发逻辑全部收敛在高阶组件的内部;而在 render props 中,除了父组件可以对数据进行分发处理之外,子组件也可以选择性地对数据进行接收
  2. 使用层面:高阶组件的使用姿势是用“函数”包裹“组件”,而 render props 恰恰相反,它强调的是用“组件”包裹“函数”

自定义Hook:设计模式解决不了所有的问题

想要去复用一段逻辑时,第一反应肯定不是“高阶函数”或者“render props”,而应该是“自定义 Hook”。Hooks 能够很好地规避掉旧时类组件中各种设计模式带来的弊端,比如说它不存在嵌套地狱,允许属性重命名、允许我们在任何需要它的地方引入并访问目标状态等

### React设计模式概述 React设计模式是指一系列用于提高代码可维护性重用性的最佳实践方法。这些模式不仅有助于简化开发过程,还能增强应用程序的性能结构清晰度[^1]。 ### 关键概念 #### 容器与展示组件模式 (Container/Presentational Components) 此模式提倡将UI分为两类角色不同的组件: - **容器组件**:负责处理业务逻辑、数据获取以及与其他系统的交互;通常不包含任何DOM标记。 - **展示组件**:专注于视图层的表现形式,只关心如何渲染接收到的数据而不涉及具体操作行为。 这种分离使得两者可以独立测试发展,并且更容易理解管理复杂的应用程序架构[^3]。 ```jsx // 展示组件 ExamplePresentational.jsx function ExamplePresentational({ title, content }) { return ( <div> <h1>{title}</h1> <p>{content}</p> </div> ); } export default ExamplePresentational; ``` ```jsx // 容器组件 ExampleContainer.jsx import React from 'react'; import axios from 'axios'; import ExamplePresentational from './ExamplePresentational'; class ExampleContainer extends React.Component { state = { data: null }; async componentDidMount() { const response = await axios.get('/api/data'); this.setState({ data: response.data }); } render() { if (!this.state.data) return <div>Loading...</div>; return <ExamplePresentational {...this.state.data} />; } } export default ExampleContainer; ``` #### 自定义 Hooks 记忆化模式 自定义Hooks允许开发者封装特定于某个功能的状态管理副作用逻辑,从而促进跨多个组件之间的复用。而记忆化技术则可以通过缓存计算结果来减少不必要的重新计算次数,进而提升应用效率。 ```javascript // useCustomHook.js import { useState, useEffect } from 'react'; function useCustomHook(initialValue) { const [value, setValue] = useState(initialValue); useEffect(() => { // 执行一些初始化或清理工作... }, []); return [value, setValue]; } export default useCustomHook; ``` ### 高阶组件(Higher Order Component, HOC) 这是一种常见的函数式编程技巧,在React中用来创建新的组件版本,其中包含了额外的功能特性或是修改后的属性配置。它接受一个现有组件作为参数并返回一个新的具有相同接口但增强了某些能力的新组件实例[^2]。 ```javascript // withLogging.js function withLogging(WrappedComponent) { return class extends React.Component { componentDidMount() { console.log('Component mounted'); } componentWillUnmount() { console.log('Component will unmount'); } render() { return <WrappedComponent {...this.props} />; } }; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值