0

我試圖做一個過濾複選框列表選項篩選出的消息顯示在飼料。我的應用程序還沒有從數據庫中獲取信息,所以我基本上是用手工創建測試方法。濾波元件上反應原住民

我擁有的變量是主題(這是一個狀態道具)和feedNews,主題是一個數組,其中包含用戶希望在Feed中看到的主題,而feedNews是存在的所有新聞組件飼料。

例如話題

this.state = { 
    topics: ['News-1','News-2','News-3'] 
} 

例如,對於feedNews

const feedNews = [ 
    {name:'News-1', comp: <FeedNews key={101} name="News-1" />}, 
    {name:'News-2', comp: <FeedNews key={102} name="News-2" />}, 
    {name:'News-3', comp: <FeedNews key={103} name="News-3" />}, 
    {name:'News-1', comp: <FeedNews key={104} name="News-1" />}, 
    {name:'News-3', comp: <FeedNews key={105} name="News-3" />} 
] 

注組件構成:每個組件上的按鍵只是一個測試

基本上我有我的渲染類的調用返回組件的濾波陣列功能:

filterFeedNews(){ 
    let topics = this.state.topics; 
    return feedNews.filter((item) => { 
     return topics.indexOf(item.name)!==-1; 
    }).map(item => item.comp); 
} 

現在,這個功能工作,每次我打開的第一次應用,但如果我真的有我的過濾選項更改主題陣列(複選框的列表),有時還有一些消失的選擇,他們也沒有了我選擇的選項。順便說一句,更新過濾功能是這樣的:

updateFilter(newsName, value){ 
    let newNewsTopics = this.state.topics; 
    if(value){ 
     newNewsTopics.push(newsName); 
    }else{ 
     newNewsTopics.splice(newNewsTopics.indexOf(newsName),1); 
    } 
    this.props.dispatch(setNewsFilter(newNewsTopics)); 
    this.setState({ 
     newsTopics: newNewsTopics, 
    }); 
} 

此功能是通過綁定每個複選框內稱爲行動

onClick(){ 
    this.action(this.name, !this.state.value); 
    this.setState({ 
     value: !this.state.value, 
    }); 
} 

我的問題是(因爲道具的名字),我是什麼這些功能做錯了,或者是「正常」要做到這一點的反應母語

PS:如果有每個主題只有一個新聞,是沒有問題的。這僅當有每個主題一個以上消息不起作用

UPDATE

我不知道這是否是問題,但如果問題是不是ListView控件過濾滾動型和渲染目的

render(){ 
     return (
      <View style={styles.root}> 
       <Toolbar home={true} options={true} title='Feed' actionOptions={this.optionsAction.bind(this)}/> 
       <View style={styles.flexContainer}> 
        <ScrollView style={styles.flexContainer}> 
         {this.filterFeedNews()} 
        </ScrollView> 
       </View> 
       <View style={styles.spacing} /> 
       {this.options()} 
      </View> 
     ); 
    } 

解決方案

所以基本上主要的甚至沒有過濾,這個問題更在R的條款輸入組件。與同事的幫助下,我不得不改變一點什麼我上面張貼的結構。 是什麼改變:

const feedNews = [ 
    {name:'News-1', ...otherProps}, 
    {name:'News-2', ...otherProps}, 
    {name:'News-3', ...otherProps}, 
    {name:'News-1', ...otherProps}, 
    {name:'News-3', ...otherProps} 
]; 

添加一個數據源到我的狀態

dataSource: ds.cloneWithRows(feedNews), 

我的過濾器進給功能改變以及適應的思想

filterFeedNews(){ 
     let topics = this.state.newsTopics; 
     let feed = feedNews.filter((item) => { 
      return topics.includes(item.name); 
     }); 
     const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); 
     this.setState({dataSource: ds.cloneWithRows(feed)}); 
    } 

我更新過濾器的新方法動作也必須改變

updateFilter(newsName, value){ 
     let newNewsTopics = this.state.topics; 
     if(value){ 
      newNewsTopics.push(newsName); 
     }else{ 
      newNewsTopics.splice(newNewsTopics.indexOf(newsName), 1); 
     } 
     this.props.dispatch(setNewsFilter(newNewsTopics)); 
     this.setState({ 
      newsTopics: newNewsTopics, 
     },() => this.filterFeedNews()); 
    } 

和我,而不是呈現滾動型的,現在有一個ListView

<ListView 
     style={styles.flexContainer} 
     dataSource={this.state.dataSource} 
     removeClippedSubviews={false} 
     renderRow={(rowData, sectionID, rowID) => this.renderRow(rowData, sectionID, rowID)} 
     enableEmptySections={true} 
/> 

臨:它沒有我不得不與我以前的做法

精讀的問題: LayoutAnimation,我用每次組件更新都不能與ListView一起使用,因此如果Feed中的消息有其圖片,用戶僅具有反饋意見

解決方案保持滾動型

在情況下,如果我想繼續我的最初的方法與滾動查看,我的解決辦法基本上是這個

updateFilter(newsName, value){ 
    let newNewsTopics = this.state.topics; 
    if(value){ 
     newNewsTopics.push(newsName); 
    }else{ 
     newNewsTopics.splice(newNewsTopics.indexOf(newsName), 1); 
    } 
    this.props.dispatch(setNewsFilter(newNewsTopics)); 
    this.setState({ 
     newsTopics: newNewsTopics, 
    }); 
} 

filterFeedNews(){ 
    let topics = this.state.topics; 
    let i = 0; 
    return feedNews.filter((item) => { 
     return topics.includes(item.name); 
    }).map((item) => { 
     return (<FeedNews key={++i} name={item.name}/>); 
    }); 
} 

凡this.state.topics維護結構(字符串數組),而feedNews基本上變成了一個對象的數組,像前面解決方案的示例中所示,然後使用filterFeedNews使用過濾器將其轉換爲函數filter,並將映射o「convert」轉換爲組件數組。 從某種意義上說,結果與ListView完全一樣,原始動畫不是「工作」的,但這是因爲實現如何完成。

解決方案的動畫

我有一個會導致所有我上面談到是因爲LayoutAnimation的實際問題的問題,每次我「刪除」新聞源與過濾選項佈局動畫結束了刪除比特定類別的新聞提要更多的內容。

我爲此道歉,因爲我認爲LayoutAnimation不是問題,並且我沒有發佈那部分代碼。

基本上是不會發生此問題刪除,對於現在的解決方案是這樣的:

LayoutAnimation.configureNext({ 
     duration: 300, 
     create: { 
      type: LayoutAnimation.Types.easeInEaseOut, 
      property: LayoutAnimation.Properties.opacity, 
     }, 
     update: { type: LayoutAnimation.Types.easeInEaseOut }, 
    }); 

如果你問我爲什麼不把刪除,那是因爲在LayouAnimation刪除沒有按」 T ON的Android很好地工作,只在iOS

再次,對不起,浪費你的時間,而不把所有的信息

回答

0

如果我沒有記錯的話,的setState不更新立即作出反應的狀態。因此,爲了防止這種情況,我建議您在回調中調用函數,如下所示:

this.setState({ 
    value: !this.state.value, 
},()=> { 
    this.action(this.name, this.state.value); 
}); 

這是否合理?

+0

另外快速提示,我個人喜歡這個用法:'this.setState({newsTopics});'因爲它很乾淨:) –

+0

這是正確的,setState將可選回調作爲第二個參數。根據文檔: setState()不會立即改變this.state,但會創建待定狀態轉換。調用此方法後訪問this.state可能會返回現有值。 無法保證setState調用的同步操作,並且可能會調用批處理調用以提高性能。 這包括在這裏的文檔:https://facebook.github.io/react/docs/react-component.html#setstate – QMFNP

+0

雖然這是做到這一點的適當方式,我同意,但不幸的是,問題是即使在那之後,它過濾和渲染 –