首页 > 解决方案 > 将道具传递给“孩子”而不覆盖明确设置的道具

问题描述

我想将一个 prop 从父组件传递给它的所有组件children,但前提是该 prop 尚未明确设置在子组件上——组件的用户应该能够轻松地覆盖传递行为。

这类似于如何将道具传递给 {this.props.children},但不同之处在于我想要“回退”而不是“覆盖”行为:我希望孩子们的现有道具优先。

具体来说,我想要实现的是一组组件Grid, Grid.Row, Grid.Column, 例如

<Grid size="big">  // A
  <Grid.Row>  // B
    <Grid.Column>  // C
      <Grid size="small">  // D
        <Grid.Column>  // E
          ...
        </Grid.Column>
      </Grid>
    </Grid.Column>
  </Grid.Row>
</Grid>

size从 A 传递到 B 到 C,从 D 传递到 E。它不会从 C 传递到 D,因为我们size在 D 元素中明确提供了我们自己的。


方法

我可以想出几种不同的方法来解决这个问题。

定义第二个“后备道具”

使用第二个道具(比如, ),我们可以用通常的方式fallbackSize无条件地设置这个道具。React.cloneElement然后子组件首先检查size,如果未定义,它会退回到fallbackSize(然后退回到它本来会退回到的任何地方,如果有的话)。

这让我觉得这是一个不受欢迎的解决方案,因为它引入了一个实际上并不代表任何东西的新道具,而只是为了解决缺乏提供“后备”的好方法的问题。

检查孩子是否有道具存在

我不确定这是否可行,但另一种“方法”是React.Children.map像往常一样映射,但以某种方式检查子元素是否存在道具,如果不存在,则使用React.cloneElement通常的方式添加它方法。

与之前的解决方案相比,这感觉干净了很多。但是,它确实需要一种可靠的方式来告诉渲染的孩子已经拥有什么道具,而且我不确定如何做到这一点(仅检查就足够了child.props.propName吗?)

依赖新的Context API

React 最近(截至 2018 年年中)引入了一个新的 Context API,允许在 React 树的子树中管理状态。这似乎是一个很好的用例,所以我认为这是要走的路。

也就是说,父级将成为提供者,在其上下文中提供传递的道具的值,而子级将成为同一上下文的消费者,如果没有明确传递道具,则回退到此。

不过,这里也有几个问题:它增加了一些复杂性,而且我不确定“传递一个道具让孩子们自动知道它”是否足够小,以至于 Context API 会矫枉过正。事实上,Context API 文档确实提供了以下通知:

不要为了避免将道具向下传递几个级别而使用上下文。坚持需要在多个级别的许多组件中访问相同数据的情况。


本质上,我想知道这里最明智和惯用的方法是什么。

标签: javascriptreactjs

解决方案


推荐阅读