2017-06-22 91 views
2

我試圖做一個搜索功能,呈現在搜索文本輸入中匹配的人的名字。React過濾狀態而不損壞它

問題是,我將狀態設置爲與搜索匹配的項目,然後初始狀態丟失,因此狀態將爲空,因此不能再進行搜索。那麼我怎麼每次都「填滿」這個狀態呢?

或者也許還有一些其他的方式,而沒有實際設置我沒有意識到的狀態。

我試圖解決這個問題,試圖在過濾器之前調用handleSearch函數時重置爲初始狀態,但那不起作用。

import React from 'react'; 
import Header from './Header'; 
import peopleData from '../persons.json'; 

class App extends React.Component { 
    constructor(){ 
    super(); 
    this.handleSearch = this.handleSearch.bind(this); 
    this.state = { 
     people: peopleData 
    } 
    } 

    handleSearch(wordToMatch){ 
    this.setState({ people: peopleData }); //Attempt to reset to initial state 
    const result = this.state.people.filter(d => { 
     const regex = new RegExp(wordToMatch, 'gi'); 
     return d.Name.match(regex); 
    }); 
    this.setState({ people: result }) 
    } 

    render() { 
    const list = this.state.people.map((d, i) => <li key={i}>{d.Name}</li>); 
    return (
     <div className="myApp"> 
     <Header 
      tagline={"testing"} 
      handleSearch={this.handleSearch} 
     /> 
     <ul className="contentBody"> 
      {list} 
     </ul> 
     </div> 
    ) 
    } 
} 

export default App; 

組件與搜索輸入:

我的數據
import React from 'react'; 

class Header extends React.Component { 
    render() { 
    return (
     <header> 
     <input 
      type="text" 
      placeholder={this.props.tagline} 
      ref={(input) => this.searchInput = input} 
      onChange={() => this.props.handleSearch(this.searchInput.value)} 
     > 
     </input> 
     </header> 
    ) 
    } 
} 

export default Header; 

的樣子

[ 
    { 
    "Name": "Adam", 
    "Born": 1971 
    }, 

    { 
    "Name": "Bob", 
    "Born": 1999 
    }, 
etc etc for 20 more names 

回答

1

setState函數不會立即更新狀態對象。因此,當您參考this.state.people時,它將引用setState呼叫之前的狀態。您可以將代碼更新爲:

handleSearch(wordToMatch) { 
    const result = peopleData.filter(d => { 
     const regex = new RegExp(wordToMatch, 'gi'); 
     return d.Name.match(regex); 
    }); 
    this.setState({ 
     people: result 
    }) 
} 
2

在設置狀態爲searchString變量handleSearch。然後在渲染方法中,不是簡單地映射狀態,而是首先過濾人員列表,並且結果就是您所映射的。

變化:

const list = this.state.people.map((d, i) => <li key={i}>{d.Name}</li>); 

到這一點:

const list = this.state.people.filter(d => { 
    const regex = new RegExp(this.state.searchString, 'gi'); 
    return d.Name.match(regex); 
}).map((d, i) => <li key={i}>{d.Name}</li>); 

這樣,列表中的狀態將保持不變,並渲染時你過濾。