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

虽然这是做到这一点的适当方式,我同意,但不幸的是,问题是即使在那之后,它过滤和渲染 –

相关问题