React中的设计模式 - 组合组件(下)

本文介绍了在React中如何利用Context和Hook来避免多层级props传递,通过创建Compound Components(组合组件)模式,如Toggle组件,实现属性的高效传递。文章详细讲解了从初始方案到使用hook的解决方案,并给出了ToggleOn、ToggleOff和ToggleButton等子组件的示例代码,展示了如何在组件嵌套情况下优雅地管理状态和属性。
摘要由CSDN通过智能技术生成

前言

最近开始学习React,跟着Kent学,有很多干货,这里分享Compound Components组合组件的第二种模式

文中完整的示例代码可以查看 这里


一、background

之前在React中的设计模式 - 组合组件(上)中,我们提到可以通过cloneElement的方法修改给子组件加属性,从而不需要通过props向下传递,但是如果遇组件跟DOM元素嵌套之后,这个方法就不能用了,情况如下

function App() {
  return (
    <div>
      <Toggle>
        <ToggleOn>The button is on</ToggleOn>
        <ToggleOff>The button is off</ToggleOff>
        <div>
          <ToggleButton />
        </div>
      </Toggle>
    </div>
  )
}

ToggleButton被div包裹导致ToggleButton无法被Toggle clone并且被添加属性


二、解决办法

2.1 初始方案

不妨使用Context处理多组件嵌套属性传递的问题,具体来说就是Toggle其实返回一个context provider,如下

const ToggleContext = React.createContext()

function Toggle({children}) {
  const [on, setOn] = React.useState(false)
  const toggle = () => setOn(!on)
  return (
    <ToggleContext.Provider value={{on, toggle}}>
	  {children}
    </ToggleContext.Provider>
  )
}  

2.2 使用hook

既然提供了ToggleContext,一般的最佳实践会通过hook向外提供统一的context获取方法,具体可以参考这篇文章React中Context的使用方法

const useToggle = () => {
  const context = React.useContext(ToggleContext)
  if (!context) throw new Error('no context ')
  return context
}

2.3 子组件获取属性

基本用法就是调用前面的hook,获得context

function ToggleOn({children}) {
  const context = useToggle()
  const {on} = context
  return on ? children : null
}

function ToggleOff({children}) {
  const context = useToggle()
  const {on} = context
  return on ? null : children
}

function ToggleButton(props) {
  const context = useToggle()
  const {on, toggle} = context
  return <Switch on={on} onClick={toggle} {...props} />
}

以上的方法也是通让可以避免组件props多层级传递,并且useContext的很多逻辑也封装得很好,只要注意使用ToggleOn ToggleOff或者ToggleButton的时候用Toggle组件包裹一下就可以了

如果用过antd这个Libray,里面Form和Form.Item跟这里的用法就很类似,Form.Item使用的时候需要被Form包裹


总结

更好传递props会使得代码更容易被使用,当多层级传递props的时候不妨考虑使用Compound Components组合组件的的方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值