2016-07-23 18 views
0

我在我的React.js(+ Redux)应用程序中制作高阶组件,以抽象功能来过滤从输入元素接收到的字符串列表。如何在React.js中创建通用的'过滤器'高阶组件?

我的过滤HOC是,

filter.js

import React, { Component } from 'react' 

export default function Filter(FilteredComponent) { 
    return class FilterComponent extends Component { 
    constructor(props) { 
     super(props)  
    } 

    generateList() { 
     if (this.props.searchTerm !== undefined) { 
     let re = new RegExp(state.searchTerm,'gi') 
     return this.props.currencyList.filter((c) => c.match(re)) 
     } 
     else { 
     return this.props.currencyList 
     } 
    } 

    render() { 
     return (
     <FilteredComponent 
      filteredList={this.generateList()} 
      {...this.props} 
     /> 
    ) 
    } 
    } 
} 

现在,我无法访问filteredList作为props.filteredList在SearchResults组件。

的成分,显示列表是

SearchResults.js

import React from 'react' 

const SearchResults = (props) => { 
    const listData = props.filteredList.map (item => <div>{item}</div>) 

    return (
    <div> 
     Here are the search results. 
     <br /> 
     <input 
     type="text" 
     value={props.searchTerm} 
     onChange={props.setSearchTerm} 
     /> 
     {listData} 
    </div> ) } 

export default SearchResults 

如何去这件事吗?

编辑:

添加容器组件为了更清楚:

SearchContainer.js

import {connect} from 'react-redux' 
import SearchResults from '../components/SearchResults' 
import * as a from '../actions' 
import Filter from '../enhancers/filter' 

const getSearchTerm = (state) => (state.searchTerm === undefined) ? '' : state.searchTerm 

const mapStateToProps = (state) => { 
    return { 
    searchTerm: getSearchTerm(state), 
    currencyList: state.currencyList 
    } 
} 

const mapDispatchToProps = (dispatch) => { 
    return { 
    setSearchTerm: (e) => { 
     dispatch(a.setSearchTerm(e.target.value)) 
    } 
    } 
} 

const SearchResultsContainer = connect(
    mapStateToProps, 
    mapDispatchToProps 
)(SearchResults) 

export default Filter(SearchResultsContainer) 
+0

对我来说看起来不错。该错误可能与周围的接线代码有关?你是如何申请HOC的?也许你可以进一步隔离这个bug。 – amann

回答

1

包装函数中的'state.searchTerm'是什么?我有一种感觉,你的意思是this.props.searchTerm。另外,你不需要es6类中的空构造函数。此外,通过容器上的mapstatetoprops中的选择器可以更好地完成此工作。

编辑: 此外,您需要包装实际的“哑”组件,而不是连接调用的结果。这样,您的Redux商店就会连接到您的Filter组件,并在商店更改时重新显示。

-1

generateList()不是反应性的。当搜索词被改变时它不会被触发。

SearchResults应该是有状态的容器组件。列表组件应通过接收搜索项作为道具来响应搜索项的更改。 generateList应该是列表组件的componentWillReceiveProps的功能。

+0

是的,这基本上是我无法想象的。 我在原始文章中提供了其他信息。 – purezen

+0

{... this.props}是错误的。它指向FilterComponent的空道具。过滤功能并不整齐。最好在SearchResults组件中写一个componentWillReceiveProps来完成过滤。 – vijayst

+0

searchTerm对于SearchResults组件是如此本地化,因此将它放入Redux存储区是没有意义的。除非有其他组件依赖于searchTerm,否则不需要为其创建动作。 – vijayst

1

我们首先将组件看作一个接受道具并返回虚拟DOM的函数。

因此SearchResult中部件采用这些道具:

  • filteredList
  • SEARCHTERM
  • setSearchTerm

创建由connect()创建的高阶分量提供这些道具:

  • SEARCHTERM
  • currencyList

Filter()高次成分:

  • 需要currencyList
  • 提供filteredList

因此,你必须接线像这样,使每个部分收到它需要的道具:

connect(...)FilterSearchResult

它应该是这样的:

export default connect(...)(Filter(SearchResult)) 

或者,如果你使用recompose

const enhance = compose(connect(...), Filter) 

export default enhance(SearchResult) 

compose()从右T包装组件o离开了。因此,最左边的高阶分量成为最外边的分量。这意味着道具将从左向右流动。


请注意:state.searchTermFilterComponent#generateList应该是this.props.searchTerm

相关问题