为每个嵌套 children 分配样式和道具
Assign style and props to each nested children
我想select主动将一些道具传递给每个 children 元素并为每个元素设置样式。
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>
)
我注意到我不能简单地遍历并将 props 传递给每个 child
const Burger = ({children, ...rest}) => (
<p>I'm a burger... </p>
{children.map(Child => <Child {...rest} />) } // error
)
在 <router>
中无法使用渲染函数。它打破了嵌套路由,如果 children 的数量不确定,我不喜欢为每个 children 手动输入道具。
...
<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 解决方案(情感)到 select 并为 <Burger/>
的每个直接后代设置样式,但这似乎也不适用于此案例.
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 的解决方案并不令人满意,因为如果每个 children 太大或嵌套太多,应该会对性能产生一些影响。
有没有其他方法可以实现我想要的?谢谢。
您的第一个解决方案应该可行。您必须在 return 语句中仅使用一个组件。所以我添加了 <>(shorthand 用于片段)。并且您应该使用双花括号进行解构(第一个用于在 jsx 中使用 js 代码,第二个用于对象解构语法)。
const Burger = ({children, ...rest}) => (
<>
<p>I'm a burger... </p>
{children.map(Child => <Child {{...rest}} />) } // error
</>
)
我用 Peter 的回答解决了这个问题,但用 React.Children
代替
const Parent = ({children, myProps}) => (
<>
...
{React.Children.map(children || null, (child, index) => {
return (
<child
{...child.props}
key={index}
myProps={myProps}
style={someStyle}
/>
);
})}
...
<>
我想select主动将一些道具传递给每个 children 元素并为每个元素设置样式。
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>
)
我注意到我不能简单地遍历并将 props 传递给每个 child
const Burger = ({children, ...rest}) => (
<p>I'm a burger... </p>
{children.map(Child => <Child {...rest} />) } // error
)
在 <router>
中无法使用渲染函数。它打破了嵌套路由,如果 children 的数量不确定,我不喜欢为每个 children 手动输入道具。
...
<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 解决方案(情感)到 select 并为 <Burger/>
的每个直接后代设置样式,但这似乎也不适用于此案例.
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 的解决方案并不令人满意,因为如果每个 children 太大或嵌套太多,应该会对性能产生一些影响。
有没有其他方法可以实现我想要的?谢谢。
您的第一个解决方案应该可行。您必须在 return 语句中仅使用一个组件。所以我添加了 <>(shorthand 用于片段)。并且您应该使用双花括号进行解构(第一个用于在 jsx 中使用 js 代码,第二个用于对象解构语法)。
const Burger = ({children, ...rest}) => (
<>
<p>I'm a burger... </p>
{children.map(Child => <Child {{...rest}} />) } // error
</>
)
我用 Peter 的回答解决了这个问题,但用 React.Children
代替
const Parent = ({children, myProps}) => (
<>
...
{React.Children.map(children || null, (child, index) => {
return (
<child
{...child.props}
key={index}
myProps={myProps}
style={someStyle}
/>
);
})}
...
<>