React + MaterialUi处理IconMenu和ListItem中的操作

时间:2017-01-01 13:25:42

标签: javascript reactjs material-ui

我正在学习反应,我尝试基于material-ui创建简单的TODO,我在处理IconMenu菜单操作时遇到问题,菜单显示在listItem元素中。此时我不知道在菜单中单击删除操作时如何使用项目名称作为参数触发deleteItem函数。

const iconButtonElement = (
    <IconButton touch={true} tooltip="More" tooltipPosition="bottom-left">
        <MoreVertIcon color="black"/>
    </IconButton>
);

const rightIconMenu = (
    <IconMenu iconButtonElement={iconButtonElement}>
        <MenuItem value="done" leftIcon={<Done />}>Mark as done</MenuItem>
        <MenuItem value="delete" leftIcon={<Delete />}>Delete</MenuItem>
    </IconMenu>
);

class TodoElements extends Component {
    deleteItem(nameProp)
    {
        this.props.delete(nameProp);
    }
    render() {
        var listItemRender = function(item) {
            return <ListItem key={item.name} primaryText={item.name} style={listItemStyle} rightIconButton={rightIconMenu}/>
        };
        listItemRender = listItemRender.bind(this);
        return (
            <List>
                {this.props.items.map(listItemRender)}
            </List>
        )
    }
}

2 个答案:

答案 0 :(得分:1)

据我所知,您应该可以向onChange添加IconMenu处理程序。因此,您的rightIconMenu可能如下所示:

const RightIconMenu = ({onChange}) => (
    <IconMenu iconButtonElement={iconButtonElement} onChange={onChange}>
        <MenuItem value="done" leftIcon={<Done />}>Mark as done</MenuItem>
        <MenuItem value="delete" leftIcon={<Delete />}>Delete</MenuItem>
    </IconMenu>
);

然后你可以在你的TodoElements中使用它:

class TodoElements extends Component {
    constructor(props){
        super(props);

        this.state = {
            items: props.items
        };
    }

    createChangeHandler = (nameProp) => {
        return (event, value) => {
            if(value==="delete"){
                this.deleteItem(nameProp);
            }
        };
    }

    deleteItem = (nameProp) =>
    {
        this.setState({ 
            items: this.state.items.filter((item) => {
                return item.name !== nameProp);
            })
        });
    }

    render() {
        return (
            <List>
            {this.state.items.map((item) => {
                <ListItem key={item.name} primaryText={item.name} style={listItemStyle} 
                    rightIconButton={<RightIconMenu onChange={this.createChangeHandler(item.name)} />}/>
            })}
            </List>
        )
    }
}

替代

作为替代解决方案,您可以将onClick处理程序绑定到删除MenuItem。我可能会这样实现它:

const RightIconMenu = ({onDelete}) => (
    <IconMenu iconButtonElement={iconButtonElement}>
        <MenuItem value="done" leftIcon={<Done />}>Mark as done</MenuItem>
        <MenuItem value="delete" leftIcon={<Delete />} onClick={onDelete}>Delete</MenuItem>
    </IconMenu>
);

然后替换TodoElements中的相应函数:

createChangeHandler = (nameProp) => {
    return (event, value) => {
        this.deleteItem(nameProp);
    };
}
render() {
    return (
        <List>
        {this.state.items.map((item) => {
            <ListItem key={item.name} primaryText={item.name} style={listItemStyle} 
                rightIconButton={<RightIconMenu onDelete={this.createDeleteHandler(item.name)} />}/>
        })}
        </List>
    )
}

至于处理项目列表的状态,您应该看一下全局状态管理,例如Redux。

答案 1 :(得分:0)

我认为一个更好的方法是使用每个MenuItem的onTouchTap,因此onChange函数不会有一个开关或许多if语句。 当我遍历所有菜单项时,我实际上正在使用它, 对我来说,它看起来像这样:

                        _.map(menuItems, (currItem, index) => {
                        return (<MenuItem primaryText={currItem.primaryText}
                                          rightIcon={currItem.rightIcon}
                                          leftIcon={currItem.leftIcon}
                                          key={`menu-item-${index}`}
                                          value={currItem.value}}
                                          onTouchTap={currItem.onTouchTap}/>)
                    })