React Native實(shí)戰(zhàn)開發(fā)9:篩選todo list

本教程內(nèi)容和https://zhiwehu.gitbooks.io/react-native/content/ 同步更新。

篩選todo list

在本小節(jié)里,我們將在footer里增加幾個(gè)按鈕,用于篩選todo list,分別是顯示所有的todo,顯示沒有完成的todo以及顯示所有完成的todo。

在footer.js里,我們將導(dǎo)入TouchableOpacity來生成幾個(gè)按鈕。

// 定義Footer類,這個(gè)類是Component的子類
// 定義Footer類,這個(gè)類是Component的子類
class Footer extends Component {
  /*
   實(shí)現(xiàn)Header類的render方法,這個(gè)方法返回一個(gè)View,顯示Footer
   */
  render() {
    return (
      <View style={styles.container}>
        <View style={styles.filters}>
          <TouchableOpacity style={styles.filter} onPress={() => this.props.onFilter('ALL')}>
            <Text>全部</Text>
          </TouchableOpacity>
          <TouchableOpacity style={styles.filter} onPress={() => this.props.onFilter('ACTIVE')}>
            <Text>未完成</Text>
          </TouchableOpacity>
          <TouchableOpacity style={styles.filter} onPress={() => this.props.onFilter('COMPLETE')}>
            <Text>已完成</Text>
          </TouchableOpacity>
        </View>
      </View>
    );
  }
}

對(duì)于每個(gè)按鈕,我們會(huì)綁定onPress事件一個(gè)方法,和之前一樣,我們將不在footer.js里去實(shí)現(xiàn)這個(gè)方法,而是通過props從上層組件中傳遞進(jìn)來。

在app.js里,我們將來實(shí)現(xiàn)onPress事件上綁定的方法。

首先我們需要?jiǎng)?chuàng)建一個(gè)工具方法,這個(gè)工具方法將在很多地方通用,這個(gè)工具方法傳遞進(jìn)去2個(gè)參數(shù) :filtertodos,filter表示篩選條件,可以是ALL,ACTIVE或者是COMPLETE中的一個(gè)值,分別代表了全部,未完成以及全部完成的todo。todos表示需要進(jìn)行篩選的todo列表。

這個(gè)方法如下:

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里定義一個(gè)方法:

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

這個(gè)方法非常簡(jiǎn)單,當(dāng)用戶點(diǎn)擊一個(gè)篩選條件的時(shí)候,將filter傳遞過來,使用我們上面定義的工具方法,得到篩選過后的列表,調(diào)用我們之前定義的 setSource方法,重新設(shè)置app.state的值,注意setSource第三參數(shù),我們需要將用戶這時(shí)的filter傳遞給app.state.filter,所以我們要在state里增加一個(gè)新的變量filter,默認(rèn)值是ALL。

// 初始化狀態(tài)
    this.state = {
      filter: "ALL",
      value: "",
      items: [],
      dataSource: ds.cloneWithRows([])
    };

接下來我們只需要在app.js里調(diào)用Footer組件里,將這個(gè)方法傳遞給Footer組件。

<Footer
  onFilter = {this.handleFilter}
/>

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

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

OK現(xiàn)在我們的filter已經(jīng)起作用了,但是經(jīng)過測(cè)試,我們發(fā)現(xiàn)當(dāng)你增加一個(gè)新todo,或者是刪除一個(gè)todo,或者是改變一個(gè)todo的狀態(tài)時(shí),我們的列表又重新顯示所有的數(shù)據(jù)了,為了解決這個(gè)問題,我們只需要在對(duì)應(yīng)的handleAddItem,handleRemoveItem以及handleToggleComplete這幾個(gè)方法里,對(duì)setSource方法里,調(diào)用我們的工具方法filterItems來篩選數(shù)據(jù)再傳給app.state

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

最后,我們將state.filter也傳給Footer組件,用于顯示當(dāng)前的filter是什么。

<Footer
  filter = {this.state.filter}
  onFilter = {this.handleFilter}
/>

在Footer組件里,可以使用this.props.filter來獲取當(dāng)前的filter,使用style來顯示一個(gè)外邊框,來突出顯示當(dāng)前選中的filter。

render() {
  const {filter} = this.props;
  return (
    <View style={styles.container}>
      <View style={styles.filters}>
        <TouchableOpacity style={[styles.filter, filter === 'ALL' && styles.selected]} onPress={() => this.props.onFilter('ALL')}>
          <Text>全部</Text>
        </TouchableOpacity>
        <TouchableOpacity style={[styles.filter, filter === 'ACTIVE' && styles.selected]} onPress={() => this.props.onFilter('ACTIVE')}>
          <Text>未完成</Text>
        </TouchableOpacity>
        <TouchableOpacity style={[styles.filter, filter === 'COMPLETE' && styles.selected]} onPress={() => this.props.onFilter('COMPLETE')}>
          <Text>已完成</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
}

運(yùn)行結(jié)果如下。
![](https://zhiwehu.gitbooks.io/react-native/content/assets/filter todo list.png)

本節(jié)代碼:https://github.com/zhiwehu/todo/tree/filter

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容