做有态度的前端团队

网易FEG前端团队

React组件间通信

近期为了练习react,自己写了一个Demo,功能很简单,展示员工信息列表,支持按性别和姓名筛选。效果如下:

默认:

1.png

筛选:

2.png
3.png
4.png

删除:

5.png

引用的文件如下:

    <script src="js/react.js"></script>
    <script src="js/react-dom.js"></script>
    <script src="js/browser.min.js"></script>

核心代码:

<body>
    <div class="table"></div>
    <script type="text/babel">
// 测试数据
var _score = [
    {name: '张三', gender: '男', phone: 18826481139, age: 28, _id:0},
    {name: '李四', gender: '男', phone: 18826481140, age: 48, _id:1},
    {name: '大妹', gender: '女', phone: 18826481142, age: 30, _id:2},
    {name: '王五', gender: '男', phone: 18826481143, age: 25, _id:3},
    {name: '赵钱', gender: '男', phone: 18826481145, age: 32, _id:4},
    {name: '二妹', gender: '女', phone: 18826481148, age: 27, _id:5}
];
 
var StaffTable = React.createClass({
    getInitialState: function () {
        return {
            genderFilter: 0,
            nameFilter: '',
            data: _score,
            modifyScore: null,
            className: 'dialog modify'
        }
    },
    onGenderChange: function (gender) {
        this.setState({genderFilter: gender});
    },
    onDeleteItem: function (id) {
        var data = this.state.data.map(function (item) {
            if(item._id === id) {
                item.deleteFlag = true;
            }
            return item;
        });
 
        this.setState(data, data);
    },
    onNameChange: function (name) {
        this.setState({nameFilter: name});
    },
    render: function () {
        return (
            <div>
               <GenderFilter onGenderChange={this.onGenderChange} genderFilter={this.state.genderFilter}/>
               <NameFilter onNameChange={this.onNameChange} nameFilter={this.state.nameFilter}/>
               <ScoreTable
                    scoreNotes={this.state.data}
                    genderFilter={this.state.genderFilter}
                    nameFilter={this.state.nameFilter}
                    deleteItem={this.onDeleteItem}
                    modifyItem={this.onModify}
               />
           </div>
        );
    }
});
 
var GenderFilter = React.createClass({
    genderChangeHandler: function () {
        this.props.onGenderChange(this.refs.genderFilter.getDOMNode().value);
    },
    render: function () {
        return (
            <div className="condition-item">
                <label>
                    <span>按性别筛选</span>
                    <select onChange={this.genderChangeHandler} ref="genderFilter">
                        <option value="0">All</option>
                        <option value="1">男</option>
                        <option value="2">女</option>
                    </select>
                </label>
            </div>
            );
    }
});
 
var NameFilter = React.createClass({
    nameChangeHandler: function () {
        this.props.onNameChange(this.refs.nameFilter.getDOMNode().value);
    },
    render: function () {
        return (
            <div className="condition-item">
                <label>
                    <span>按姓名筛选</span>
                    <input type="text" ref="nameFilter" onChange={this.nameChangeHandler} value={this.props.nameFilter}/>
                </label>
            </div>
            );
    }
});
 
var ScoreTable = React.createClass({
    deleteItemHandler: function (id) {
        this.props.deleteItem(id);
    },
    modifyItem: function (id) {
        this.props.modifyItem(id);
    },
    render: function () {
        var scoreNotes = [];
        var genderFilter = +this.props.genderFilter,
            nameFilter = this.props.nameFilter,
            GENDER = ['', '男', '女'],
            _this = this;
 
        this.props.scoreNotes.map(function (scoreItem) {
            if (genderFilter !== 0 && nameFilter === '') {
                // 仅genderfilter生效
                if (GENDER[genderFilter] === scoreItem.gender) {
                    !scoreItem.deleteFlag && scoreNotes.push(<ScoreItem score={scoreItem} onDelete={_this.deleteItemHandler} onModify={_this.modifyItem}/>);
                }
                return;
            }
 
            if (genderFilter === 0 && nameFilter !== '') {
                // 仅nameFilter生效
                if (scoreItem.name === nameFilter) {
                    !scoreItem.deleteFlag && scoreNotes.push(<ScoreItem score={scoreItem} onDelete={_this.deleteItemHandler} onModify={_this.modifyItem}/>);
                }
                return;
            }
 
            if (genderFilter !== 0 && nameFilter !== '') {
                // 两个filter都生效
                if (GENDER[genderFilter] === scoreItem.gender && scoreItem.name === nameFilter) {
                    !scoreItem.deleteFlag && scoreNotes.push(<ScoreItem score={scoreItem} onDelete={_this.deleteItemHandler} onModify={_this.modifyItem}/>);
                }
                return;
            }
 
            !scoreItem.deleteFlag && scoreNotes.push(<ScoreItem score={scoreItem} onDelete={_this.deleteItemHandler} onModify={_this.modifyItem}/>);
        });
 
        return (
            <table>
                <thead>
                    <tr>
                        <th>姓名</th>
                        <th>性别</th>
                        <th>电话</th>
                        <th>年龄</th>
                        <th>操作</th>
                    </tr>
                </thead>
                <tbody>
                    {scoreNotes}
                </tbody>
            </table>
            );
    }
});
 
var ScoreItem = React.createClass({
    deleteHandler: function (e, id) {
        this.props.onDelete(this.props.score._id);
    },
    modifyHandler: function () {
        this.props.onModify(this.props.score._id);
    },
    render: function () {
        var score = this.props.score;
 
        return (
            <tr>
                <td>{score.name}</td>
                <td>{score.gender}</td>
                <td>{score.phone}</td>
                <td>{score.age}</td>
                <td><a href="javascript:void(0);" className="trigger" onClick={this.deleteHandler}>删除</a></td>
            </tr>
            );
    }
});
 
ReactDOM.render(<StaffTable />, document.querySelector('.table'));
    </script>
</body>

说明:

StaffTable有三个子组件:GenderFilter, NameFilter, InformationTable。其中,InformationTable又包含若干个子组件InformationItem。

1、当选择性别后,要对InformationItem做筛选
2、当输入姓名后,要对InformationItem做筛选
3、当同时选择性别,输入姓名,两个筛选条件对InformationItem生效
4、点击某InformationItem的删除按钮后,删除此InformationItem

备注:

虽然能成功操作,但是有报错,代码尚待优化。

手机阅读请扫描下方二维码: