React Native实战开发9:筛选todo list

本教程内容和https://zhiwehu.gitbooks.io/react-native/content/ 同步更新。

筛选todo list

在本小节里,我们将在footer里增加几个按钮,用于筛选todo list,分别是显示所有的todo,显示没有完成的todo以及显示所有完成的todo。

在footer.js里,我们将导入TouchableOpacity来生成几个按钮。

// 定义Footer类,这个类是Component的子类
// 定义Footer类,这个类是Component的子类
class Footer extends Component {
  /*
   实现Header类的render方法,这个方法返回一个View,显示Footer
   */
  render() {
    return (
      
        
           this.props.onFilter('ALL')}>
            全部
          
           this.props.onFilter('ACTIVE')}>
            未完成
          
           this.props.onFilter('COMPLETE')}>
            已完成
          
        
      
    );
  }
}

对于每个按钮,我们会绑定onPress事件一个方法,和之前一样,我们将不在footer.js里去实现这个方法,而是通过props从上层组件中传递进来。

在app.js里,我们将来实现onPress事件上绑定的方法。

首先我们需要创建一个工具方法,这个工具方法将在很多地方通用,这个工具方法传递进去2个参数 :filtertodosfilter表示筛选条件,可以是ALL,ACTIVE或者是COMPLETE中的一个值,分别代表了全部,未完成以及全部完成的todo。todos表示需要进行筛选的todo列表。

这个方法如下:

const filterItems = (filter, todos) => {
  return todos.filter(todo => {
    if (filter === 'ALL') return true;
    if (filter === 'ACTIVE') return !todo.complete;
    if (filter === 'COMPLETE') return todo.complete;
  });
}

然后在App component里定义一个方法:

handleFilter(filter) {
    this.setSource(this.state.items, filterItems(filter, this.state.items), {filter: filter})
  }

这个方法非常简单,当用户点击一个筛选条件的时候,将filter传递过来,使用我们上面定义的工具方法,得到筛选过后的列表,调用我们之前定义的 setSource方法,重新设置app.state的值,注意setSource第三参数,我们需要将用户这时的filter传递给app.state.filter,所以我们要在state里增加一个新的变量filter,默认值是ALL

// 初始化状态
    this.state = {
      filter: "ALL",
      value: "",
      items: [],
      dataSource: ds.cloneWithRows([])
    };

接下来我们只需要在app.js里调用Footer组件里,将这个方法传递给Footer组件。

别忘记在App的constructor方法里,使用bindhandleFilter方法bind(this)

this.handleFilter = this.handleFilter.bind(this);

OK现在我们的filter已经起作用了,但是经过测试,我们发现当你增加一个新todo,或者是删除一个todo,或者是改变一个todo的状态时,我们的列表又重新显示所有的数据了,为了解决这个问题,我们只需要在对应的handleAddItemhandleRemoveItem以及handleToggleComplete这几个方法里,对setSource方法里,调用我们的工具方法filterItems来筛选数据再传给app.state

this.setSource(newItems, filterItems(this.state.filter, newItems));

最后,我们将state.filter也传给Footer组件,用于显示当前的filter是什么。

在Footer组件里,可以使用this.props.filter来获取当前的filter,使用style来显示一个外边框,来突出显示当前选中的filter。

render() {
  const {filter} = this.props;
  return (
    
      
         this.props.onFilter('ALL')}>
          全部
        
         this.props.onFilter('ACTIVE')}>
          未完成
        
         this.props.onFilter('COMPLETE')}>
          已完成
        
      
    
  );
}

运行结果如下。
![](https://zhiwehu.gitbooks.io/react-native/content/assets/filter todo list.png)

本节代码:https://github.com/zhiwehu/todo/tree/filter

你可能感兴趣的:(React Native实战开发9:筛选todo list)