React入门实践之TodoList: 添加事件和搜索框
在上篇文章中,我们使用React实现了一个TodoList,可以显示基本的待办事项的列表,今天我们继续添加一些功能,比如选中一个TodoItem的checkbox进而可以改变它的完成状态,添加一个搜索框,在搜索框中输入关键字可以对多条数据进行过滤。 var TodoList = React.createClass({
getInitialState: function() {
return {
data: []
};
},componentDidMount: function() {
var mockData = [
{id: 1,name: "report the updates to Boss",time: "9:30"},{id: 2,name: "Stand-up meeting",time: "10:00"},{id: 3,name: "Draw up a plan for next step",time: "11:00"}
];
this.setState({
data: mockData
});
},render: function() {
var todoItems = this.state.data.map(function(todo) {
return (
//passing the whole todo object as a property
<TodoItem key={todo.id} todo={todo}/>
);
});
return (
<div className="todoList">{todoItems}</div>
);
}
});
在上面的代码中,我们改进了TodoItem属性的传递方式,直接把一个todo数据对象作为属性提供给TodoItem,这样更利于开发过程中的数据处理。接下来,我们也要对TodoItem模块进行改进,代码如下: var TodoItem = React.createClass({
//will be called after clicking the checkbox
handleClick: function(event) {
var todoData = this.props.todo;
todoData.hasDone = !todoData.hasDone;
//re-render the view
this.setState({
hasDone: todoData.hasDone
});
//Ajax handling maybe
//updateTodo(this.props.todo);
},getInitialState: function() {
return {
hasDone: false
};
},componentDidMount: function() {
this.setState({
hasDone: this.props.todo.hasDone
});
},render: function() {
var classList = ['todoItem'];
this.state.hasDone && classList.push('hasDone'); //add a 'hasDone' class after checkbox is checked
var classNames = classList.join(' ');
return (
//adding 'onClick' property on checkbox to bind a click handler
<div className={classNames}>
<input type="checkbox" onClick={this.handleClick} checked={this.props.todo.hasDone}/>
<div className="name">{this.props.todo.name}</div>
<div className="time">{this.props.todo.time}</div>
</div>
);
}
});
这一部分改动的较多,我们仔细来分析每个部分的功能。 .todoItem.hasDone > div { text-decoration: line-through; }
现在我们来看一下最终的页面效果,如图所示,当我们点击第一个TodoItem后是这个样子的: var SearchBox = React.createClass({
render: function() {
return (
<div className="searchBox">
<input type="text" placeholder="type in keywords to search"/>
</div>
);
}
});
然后声明对应的CSS样式: .searchBox { width: 400px; height: 100%; margin: 0 auto; }
.searchBox input { width: 100%; height: 30px; border: none; padding: 5px 15px; border-radius: 2px; font-size: 14px; }
最后还需在TodoList模块的render方法中把SearchBox添加进去: render: function() {
var todoItems = this.state.data.map(function(todo) {
return (
<TodoItem key={todo.id} todo={todo}/>
);
});
return (
<div className="todoList">
<SearchBox/>
{todoItems}
</div>
);
}
现在可以预览一下页面效果: var TodoList = React.createClass({
handleSearchTextUpdate: function(searchText) {
this.state.searchText = searchText;
this.setState(this.state);
},getInitialState: function() {
return {
data: [],searchText: '' //adding a searchText,it will be used in render method
};
},time: "11:00"}
];
this.state.data = mockData;
this.setState(this.state);
},render: function() {
var state = this.state;
//filter the data first and then call map function
var todoItems = state.data.filter(function(todo) {
return todo.name.toLowerCase().indexOf(state.searchText.toLowerCase()) > -1;
}).map(function(todo) {
return (
<TodoItem key={todo.id} todo={todo}/>
);
});
return (
//adding a 'onSearchTextUpdate' callback,it will be called when text changes in search input
<div className="todoList">
<SearchBox onSearchTextUpdate={this.handleSearchTextUpdate}/>
{todoItems}
</div>
);
}
});
可以看到,在 var SearchBox = React.createClass({
handleChange: function(event) {
var newInput = event.target.value;
//call the onSearchTextUpdate in props
this.props.onSearchTextUpdate(newInput);
},render: function() {
return (
//adding a 'onChange' to monitor the value changes
<div className="searchBox">
<input type="text" onChange={this.handleChange} placeholder="type in keywords to search"/>
</div>
);
}
});
过滤功能只是在TodoList和SearchBox之间的交互,TodoItem是不需要任何改动的,所以只需弄清楚SearchBox和TodoList之间的交互,就可以很快实现一个过滤功能,下面是我们最终的页面效果: (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |