《react 实战系列》children 透传

接水怪

共 3136字,需浏览 7分钟

 ·

2021-09-25 18:23

问题

react 三层组件,也就是常说的爷孙组件,怎么通信?

方案一,props 直接传


我称之为暴力写法(因为这种方式,其实不管嵌套多少层,都可以这样写,很暴力),直接看代码。

function Top () {
  const [middleData] = useState(1);
  const [bottomData] = useState(2);
  
  return <Middle middleData={middleData} bottomData={bottomData}  />
}

function Middle ({ middleData, bottomData }) {
  return (
    <>
      {middleData}
      <Bottom bottomData={bottomData} />
    </>
  )
}

function Bottom ({ bottomData }) {
  return <>{bottomData}</>
}

Bottom 组件通过 Middle 组件中转,成功拿到了 Top 组件的值。那这样有什么问题呢?

这样写,如果 Top 组件需要传递其它数据给到 Bottom,就意味着 Middle 组件需要加字段。

方案一改进版


我们把所有需要从 Top 传递给 Bottom 的封装为一个字段,比如叫 allBottomProps。

function Top () {
  const [middleData] = useState(1);
  const [bottomData] = useState(2);
  
  return <Middle middleData={middleData} allBottomProps={{ bottomData: bottomData }}  />
}

function Middle ({ middleData, allBottomProps }) {
  return (
    <>
      {middleData}
      <Bottom {...allBottomProps} />
    </>
  )
}

function Bottom ({ bottomData }) {
  return <>{bottomData}</>
}

这样改进之后,Top 组件需要给 Bottom 传递其它数据时,就不需要去动 Middle 的代码了。那这样还有什么问题吗?能不能把 Middle 这层抹平,不然即使封装在一个字段,还是逃脱不了 Middle 的魔爪。我想直接测试 Middle 时,还得造一份 Bottom 组件的数据。

方案二,通过 children 透传

先看代码(类似于 vue 中的 slot),再来分析

function Top () {
  const [middleData] = useState(1);
  const [bottomData] = useState(2);
  
  return (
    <>
      <Middle middleData={middleData}>
        <Bottom bottomData={bottomData} />
      </Middle>
    </>
  )
}

function Middle ({ middleData, children }) {
  return (
    <>
      {middleData}
      {children}
    </>
  )
}

function Bottom ({ bottomData }) {
  return <>{bottomData}</>
}

利用 children 处理之后,优点比较明显:

  • Middle 组件变得更加的独立,跟 Bottom 不再耦合
  • 直接在 Top 组件就可以进行数据的分发
  • 直接在 Top 组件就可以看清楚组件的结构,很清晰

小结

业务代码,并且嵌套的层级不算深,可以试试 children 透传。结构简单、清晰。

下期预告

十一将至,相信很多小伙伴都要骑上心爱的小摩托出去旅游。作为一个土生土长的重庆人,决定简短写一篇攻略(主要是吃),让去重庆的小伙伴不踩雷,吃到正宗的美食。

像很多网红点都是不推荐去吃的,商业化太严重,已经变得不纯粹了。具体下篇细说咯~~~


浏览 113
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报