ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

接口思维:如何使用 Context API 构建灵活、可维护的 React 组件

2023-03-17 11:59:18  阅读:308  来源: 互联网

标签:编程 Context API React


React 文档提到 Context 旨在在组件之间共享数据共享值,而无需显式地通过树的每个级别传递 prop(prop 钻孔问题)。

Context允许父组件向其下方树中的任何组件提供一些信息——无论多深——而无需通过 props 显式传递。

要了解有关钩子的更多信息,您可以在此处下载备忘单,其中包含最常见的 React 钩子以及示例和插图。

理想情况下,您可以在上下文中放置您喜欢的任何内容,只要它们小而简洁即可。React 为您提供了可以在上下文中使用哪些数据的灵活性,这也意味着没有太多好的指导。

我想讨论一种关于在上下文中可以使用什么类型的数据的模式,以便您可以最大限度地提高 React 应用程序的灵活性。

   

简而言之,当您需要一些上下文时,尽可能尝试使用接口而不是实现——即使它只是一个单例(该接口的一个不太明显的实例将是一个测试模拟)。就像在 OO 世界中一样,我们会在类中使用接口,只有在运行时我们才知道应该使用哪个实现。

例如,我们需要制作Payment支持不同国家的组件——使用不同的汇总逻辑并显示不同的货币符号。例如,在日本,四舍五入到最接近的百位更有意义。

 

所以在这种情况Payment下,组件应该依赖于一个PaymentStrategy接口,在 React 树的更高级别,我们可以“注入”该接口的不同实例,并且保持Payment自身不变。

   

介绍界

接口定义的代码片段可以是:

接口 PaymentStrategy { 
    getCurrencySign(): string; getCurrencySign (): 字符串;
    roundUp(数量:数量):数量;
}

在不同的国家,你可以实现这样的逻辑:

 AustralianStrategy 实施 PaymentStrategy { 
    getCurrencySign ( ) { 
        return  "$" ; 
    } 

    roundUp金额:数字){
        返回 数学地板(数量+ 1
    } 
}

所以在你的实际Payment组件中,我们可以使用这样的接口:

const  Payment = ( {amount, strategy}: 
  {amount: number , strategy: PaymentStrategy} ) => {   
    return <button>{strategy.roundUp(amount)}</button>; } 
}

这种方法效果很好,唯一的缺点是当我们使用 时Payment,我们需要PaymentStrategy在调用站点附近的某个地方定义一个新的。

const strategy = new  AustralianStrategy (); 

const  CheckoutPage = ( ) => { 
    //... 
    return ( 
        <Payment amount={amount} strategy={strategy} /> 
    ) 
}

该代码有点不反应。稍加改动就可以使代码更易于维护——使用 Context API。

使用反应上下文

在树的更高层,通常在应用程序根目录中,我们可以设置许多上下文。这些上下文都是正交的,这意味着它们不重叠。一个用于安全审计,一个用于日志记录,另一个用于某些业务逻辑切换。

我们可以利用国家代码来切换不同的策略:

// PaymentStrategyContext.tsx

导出 接口 PaymentStrategyContextType { 
  strategy : PaymentStrategyContext ; 
}

导出 默认createContext< PaymentStrategyContextType | >();

并在应用程序设置中:

 “./PaymentStrategyContext”导入PaymentStrategyContext const App = ( ) => { // 或从工厂获取不同国家/地区的不同策略const strategy = new AustralianStrategy (); 返回(         <LoggingContext.Provider>             <PaymentStrategyContext.Provider value={{strategy}}>                 <Route {...} />             </PaymentStrategyContext.Provider>         </LoggingContext.Provider>     ) } 

 
    
     
    






最后,我们的Pyament组件将获取从应用程序根传入的任何内容。

const  Payment = ( {amount}: {amount: number } ) => { 
    const {strategy} = useContext ( PaymentStrategyContext ); 
    
    返回<button>{strategy.roundUp(amount)}</button>; 
}

而且它也很容易测试。如果您使用的是react-testing-library,只需使用策略接口的虚假实现定义自定义呈现就足够了。(我在这篇长篇文章中详细讨论了这种模式)

将接口与 Context API 结合使用的好处是:

  1. 增加灵活性:当您想到接口时,您是在组件之间定义一个契约,允许它们在不知道彼此实现细节的情况下进行交互。这使得更改或更新组件的实现变得更加容易,而不会影响依赖它的其他组件。
  2. 更好的封装:通过为您的组件定义接口,您可以隐藏它们的内部细节并仅公开公共 API。这有助于控制代码的复杂性并使其更易于推理。
  3. 更容易维护:当你想​​到接口时,你会创建模块化和可重用的组件,随着时间的推移更容易维护。如果你需要更新一个组件,你可以这样做而不用担心破坏依赖它的其他组件。
  4. 更好的可测试性:通过为您的组件定义接口,您可以编写专注于公共 API 而忽略内部细节的测试。这使得编写涵盖所有边缘情况的综合测试变得更加容易,并确保您的代码按预期工作。

概括

使用 Context 共享数据并采用面向接口的方法可以释放出比数据共享更多的好处。尽管乍一看似乎更复杂,但在接口中思考可以增强代码的灵活性和可维护性。本质上,接口提供组件之间的契约,允许更容易的更改和更新、更好的封装和改进的可测试性。

标签:编程,Context API,React
来源:

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有