Javascript 给孩子编号
我有一个菜单组件,我希望能够对该组件中的菜单项进行编号。(然后使用菜单项编号跟踪聚焦菜单项并响应数字键盘按键。) 我当前的实现如下所示:Javascript 给孩子编号,javascript,reactjs,Javascript,Reactjs,我有一个菜单组件,我希望能够对该组件中的菜单项进行编号。(然后使用菜单项编号跟踪聚焦菜单项并响应数字键盘按键。) 我当前的实现如下所示: class Menu extends React.Component { numberChildren() { return _.chain(React.Children.toArray(this.props.children)) .filter() .map((child, i) => React.cloneElem
class Menu extends React.Component {
numberChildren() {
return _.chain(React.Children.toArray(this.props.children))
.filter()
.map((child, i) => React.cloneElement(child, {
number: i + 1
}))
.value();
}
render() {
return <div className="menu">{this.numberChildren()}</div>;
}
};
但是,对于更复杂的儿童来说,它是失败的:
<Menu>
<MenuItem>Salad</MenuItem>
<SoupOfTheDayMenuItem/>
<MenuItem>Grilled Chicken</MenuItem>
</Menu>
沙拉
烤鸡
SoupOfTheDayMenuItem
是一个包装器组件,它返回单个MenuItem
(也应枚举)或null
即使SoupOfTheDayMenuItem
返回null,在调用lodash的过滤器时仍然是真实的,因此它仍然得到数字2
有没有办法说“只为实际渲染的子对象注入此属性”或“为实际渲染somthing的子对象集”呢?或者有更好的方法来设计所有这些吗?我显然没有应用程序的所有上下文,但也许将每个子组件包装在一个包装MenuItemContainer
组件中会更有意义,该组件处理所有的索引和内容,然后让子组件执行其目的。我的意思是
class Menu extends React.Component {
render() {
return this.props.children.map((Child, i) => {
return (
<MenuItemContainer key={i}>
<Child/>
</MenuItemContainer>
)
}
}
类菜单扩展了React.Component{
render(){
返回此.props.children.map((Child,i)=>{
返回(
)
}
}
})
然后Child
可以是MenuItem
或soupfthedaymenuitem
而没有任何问题。我假设soupfthedaymenuitem
是MenuItem
的包装器或返回null。
因此,您可以尝试筛选出那些具有props.children
falsy的子项,这意味着SoupOfTheDayMenuItem
返回空值。
这应该可以做到:
numberChildren() {
return _.chain(React.Children.toArray(this.props.children))
.filter(child => child.type.displayName == 'MenuItem' || child.props.children)
.map((child, i) => React.cloneElement(child, {
number: i + 1
}))
.value();
}
如果SoupOfTheDayMenuItem
有一些项目,它们也应该被列举出来?@mklimek-是的;我更新了我的问题。谢谢。那么看看我的答案。它应该会帮助你与@Drew Schuster answer结合起来。我不确定这有什么帮助。即使MenuItemContainer
处理索引和其他东西,它将如何解决问题第二个子(例如)返回null并且不应该被索引?第二个MenuItemContainer
必须知道它不应该被索引,并且必须在它之后将它传达给MenuItemContainers
?你是对的,@mklimek上面的回答更好地解释了如何事先过滤掉空元素。这非常有效谢谢。我做了一些更改:我想你的意思是props
而不是params
?另外,它看起来像是child.type.displayName
没有为我的类设置。(我不知道为什么。)但是,即使是我的普通菜单项也有子项-因此.filter(child=>child&&child.props.children)
效果很好。当然,我很高兴它能为你工作!
numberChildren() {
return _.chain(React.Children.toArray(this.props.children))
.filter(child => child.type.displayName == 'MenuItem' || child.props.children)
.map((child, i) => React.cloneElement(child, {
number: i + 1
}))
.value();
}