[英]Filtering Components on React Native
我正在嘗試制作一個過濾復選框列表選項,以過濾掉要在Feed上顯示的新聞。 我的應用程序還沒有從數據庫獲取信息,所以我基本上是手工創建測試方法。
我擁有的變量是主題(這是一個州道具),而feedNews,主題是一個數組,其中包含用戶希望在Feed中看到的主題,而feedNews是存在於Feed中顯示的所有新聞組件。
例如主題
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,
});
}
這個函數被每個復選框中的bind作為動作調用(因為道具的名稱)
onClick(){
this.action(this.name, !this.state.value);
this.setState({
value: !this.state.value,
});
}
我的問題是,我在這些函數上做錯了什么,或者在本地反應中發生這種情況是“正常的”
PS:如果每個主題只有一個新聞,那就沒問題了。 僅當每個主題有多個新聞時,這才起作用
UPDATE
我不確定這是否是問題,但如果問題是ScrollView而不是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>
);
}
所以基本上主要是甚至不過濾,問題更多的是組件的渲染。 在同事的幫助下,我不得不改變我上面發布的結構。 改變了什么:
const feedNews = [
{name:'News-1', ...otherProps},
{name:'News-2', ...otherProps},
{name:'News-3', ...otherProps},
{name:'News-1', ...otherProps},
{name:'News-3', ...otherProps}
];
在我的州添加了一個dataSource
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());
}
而我的渲染而不是ScrollView它現在有一個ListView
<ListView
style={styles.flexContainer}
dataSource={this.state.dataSource}
removeClippedSubviews={false}
renderRow={(rowData, sectionID, rowID) => this.renderRow(rowData, sectionID, rowID)}
enableEmptySections={true}
/>
親:它沒有我以前的方法遇到的問題
Con:我每次更新組件時使用的LayoutAnimation都不能與ListView一起使用,因此如果Feed中的新聞有他們的圖片,用戶只有過濾的反饋
如果我想用Scroll View保留我的初始方法,我的解決方案基本上就是這個
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和map o“convert “進入一系列組件。 在某種程度上,結果與ListView完全相同,原始動畫不是“工作”,但這是因為實現的完成方式。
我遇到的問題導致我上面討論的所有問題實際上都是因為LayoutAnimation,每當我“刪除”帶有過濾選項的新聞源時,布局動畫最終刪除的內容超過了特定類別的新聞源。
我為此道歉,因為我認為LayoutAnimation不是問題而且我沒有發布那部分代碼。
基本上這個刪除問題不會發生,現在的解決方案是:
LayoutAnimation.configureNext({
duration: 300,
create: {
type: LayoutAnimation.Types.easeInEaseOut,
property: LayoutAnimation.Properties.opacity,
},
update: { type: LayoutAnimation.Types.easeInEaseOut },
});
如果你問為什么我沒有刪除,那是因為在LayouAnimation中刪除在Android上運行不正常,只在iOS上運行
再次,抱歉在沒有提供所有信息的情況下浪費你的時間
如果我沒有弄錯,setState不會立即更新狀態。 所以為了防止這種情況,我建議你在回調上調用函數,如下所示:
this.setState({
value: !this.state.value,
}, ()=> {
this.action(this.name, this.state.value);
});
這有道理嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.