我正在尝试从头开始使用MenuItem构建一个菜单。我正在使用React 0.14和Redux,以及CoffeeScript(cjsx)。 (我刚刚开始使用所有这些)
我被卡住了,因为我不知道如何给MenuItem提供对回调函数match = re.search(r"On ([0-9,-, ]+)Bob used ([0-9\.]+)", line.strip())
if match is not None:
... do stuff with match.group() here ...
... but not here ...
的引用。因为它们是通过onChildrenClick
生成的,所以我不知道我应该在那里添加{this.props.children}
。
Menu.cjsx
props
MenuItem.cjsx
React = require 'react'
class Menu extends React.Component
@propTypes =
children: React.PropTypes.array.isRequired
render: ->
<div className="ui pointing menu">
{this.props.children} # I don't see how I can bind the "onChildrenClick" function to the child, because they're generated outside of this scope. Maybe by looping on "this.props.children"? I tried but it wasn't successful.
</div>
onChildrenClick: (event) ->
console.log event
module.exports = Menu
以下是我如何构建菜单及其项目:
React = require 'react'
classNames = require('classnames')
class MenuItem extends React.Component
@propTypes =
label: React.PropTypes.string.isRequired
active: React.PropTypes.bool
constructor: (props) ->
super props
@state =
classes: classNames(
'ui'
'item'
'active': this.props.active
)
render: ->
<a className={@state.classes} onClick={@onClick}>
{ this.props.label }
</a>
onClick: =>
console.log Object.assign @state.classes, {active: !@state.classes.active}
@setState({classes: Object.assign @state.classes, {active: true}})
console.log @state.classes # I need to notify the parent so it can notify the current active children to get disabled.
module.exports = MenuItem
在示例中,我手动生成“菜单1 ... 3”,但它们实际上是动态生成的。
我不知道我是否在这里采取了正确的方法。也许我应该使用Redux呢?最后,我应该使用<Menu>
<MenuItem active={true} label="Menu 1"></MenuItem>
<MenuItem label="Menu 2"></MenuItem>
<MenuItem label="Menu 3"></MenuItem>
</Menu>
,因为每个MenuItem应该有自己的url(类似Angular,例如Routes
)
我也想知道给一个 MenuItem 内容的最佳方法是什么。感谢您的见解。
答案 0 :(得分:1)
这可能是React.Children的候选人,您可以将props
指定为传递给任何abritrary子元素 - 在这种情况下onClick
:
<强> Menu.jsx 强>
<div className="ui pointing menu">
{
React.Children.map(this.props.children,
function(child) {
return React.cloneElement(child, {
onClick: this.onClick
});
}.bind(this)
)
}
</div>
但我可能会建议一种替代方法,您可以将列表项传递给Menu
组件本身,然后可以单独呈现每个列表项,而不仅仅是this.props.children
:
Menu.jsx(Alt)
render() {
return (
<div className="ui pointing menu">
{
this.props.menuItems.map((item, index) => (
<MenuItem item={item} onClick={(e) => this.onClick(e, item)} }/>
)
}
</div>
)
}
答案 1 :(得分:0)
我建议将onClick
函数作为MenuItem
的道具从您呈现Menu
的任何地方传递。
E.g。
menu_wrapper.js
// This is a functional component because it is 'dumb' - does not have state
React = require('react')
Menu = require('menu')
MenuItem = require('menu_item')
menuWrapper = (props)=>
onMenuItemClick = (e)=>
console.log(e)
menuItems = ()=>
props.list.map(function(item) {
isActive = (item.label == props.activeItem)
<MenuItem onClick={onMenuItemClick} active={isActive} label={item.label}/>
}
<div id="menu-wrapper">
<Menu>
{menuItems()}
</Menu>
</div>
menu.js
// Also a 'dumb' component - component without state
React = require('react')
Menu = (props)=>
<div className="ui pointing menu">
{props.children}
</div>
module.exports = Menu
menu_item.js
React = require 'react'
classNames = require('classnames')
class MenuItem extends React.Component
@propTypes =
label: React.PropTypes.string.isRequired
active: React.PropTypes.bool
onClick: React.PropTypes.func.isRequired
constructor: (props) ->
super props
@state =
classes: classNames(
'ui'
'item'
'active': this.props.active
)
render: ->
<a className={@state.classes} onClick={@onClick}>
{ this.props.label }
</a>
onClick: (e)=>
@props.onClick(e)
console.log Object.assign @state.classes, {active: !@state.classes.active}
@setState({classes: Object.assign @state.classes, {active: true}})
console.log @state.classes # I need to notify the parent so it can notify the current active children to get disabled.
module.exports = MenuItem
最后,考虑从CoffeeScript迁移到ES6。您在CoffeeScript中获得的大部分内容现在都可以在ES6中使用,还有一些。也就是说,我确实错过了隐含的回报。