【问题标题】:Assign style and props to each nested children为每个嵌套的孩子分配样式和道具
【发布时间】:2026-01-09 17:10:01
【问题描述】:

我想有选择地将一些道具传递给每个子元素并设置它们的样式。

const Burger = ({children, ...rest}) => (
  <>
   <p>I'm a burger...</p>
   {children}
  </>
)
const Meat = ({type}) => <span>with {type?type:'no'} meat</span>
const Sauce = ({flavor}) => <span>with {flavor?flavor:'no'} sauce</span>
const Veggie = ({green}) => <span>with {green?green:'no'} greens</span>

const App = () => (
  // reach-router nesting
  <Router>
    <Burger path='burger' {...props}>
      <Sauce path='sauce' />
      <Veggie path='veggie' />
      <Meat path='meat' />
    </Burger>
  </Router>
)

我注意到我不能简单地遍历并将道具传递给每个孩子

const Burger = ({children, ...rest}) => (
   <p>I'm a burger... </p>
   {children.map(Child => <Child {...rest} />) } // error
)

&lt;router&gt; 中无法使用渲染函数。它打破了嵌套路由,如果孩子的数量不定,我不喜欢为每个孩子手动输入道具。

...
  <Router>
    <Burger path='burger' {...props}>
    {someStyle => (
      <>
        <Sauce path='sauce' style={someStyle}/>
        <Veggie path='veggie' style={someStyle}/>
        <Meat path='meat' style={someStyle}/>
      </>
    )}
    </Burger>
  </Router>
...

接下来,我继续尝试使用 css-in-js 解决方案(情感)来选择和设置&lt;Burger/&gt; 的每个直系后代的样式,但这在这种情况下似乎也不起作用。

const styleAllChild = css`
  & > * : {
    margin-bottom: 10px;
  }
`
...
  <Router>
    <Burger path='burger' css={styleAllChild} {...props}>
      <Sauce path='sauce' />
      <Veggie path='veggie' />
      <Meat path='meat' />
    </Burger>
  </Router>
...

最后,我发现将 children.map 与 React.cloneElement 结合使用的解决方案并不令人满意,因为如果每个孩子太大或嵌套太多,应该会影响性能。

还有其他方法可以实现我想要的吗?谢谢。

【问题讨论】:

    标签: javascript css reactjs emotion reach-router


    【解决方案1】:

    您的第一个解决方案应该有效。您必须在 return 语句中只使用一个组件。所以我添加了 (片段的简写)。并且你应该使用双花括号进行解构(第一个用于在 jsx 中使用 js 代码,第二个用于对象解构语法)。

    const Burger = ({children, ...rest}) => (
      <>
       <p>I'm a burger... </p>
       {children.map(Child => <Child {{...rest}} />) } // error
      </>
    )
    

    【讨论】:

      【解决方案2】:

      我用彼得的答案解决了这个问题,但用React.Children 代替

      const Parent = ({children, myProps}) => (
        <>
        ...
        {React.Children.map(children || null, (child, index) => {
          return (
            <child 
              {...child.props}
              key={index}
              myProps={myProps}
              style={someStyle} 
            />
          );
        })}
        ...
        <>
      

      【讨论】: