2016-07-23 19 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

相關問題