在状态更新后,React不会重新发送DOM

时间:2018-04-02 19:32:18

标签: javascript reactjs

我在状态更改后重新呈现DOM时出现问题,以下是组件的代码:

<ul>
    { this.state.musicLibraryItems }
</ul>

我有一个过滤函数,它从文本输入中获取值,并根据标题是否包含文本输入的值来过滤musicLibraryItems,我在以下函数中执行此操作:

filterMusicLibrary(value) {
    let musicLibraryItems = [];
    this.state.musicGet.map(music => {
        if(music.title.includes(value)) {
            console.log(music.title)
            musicLibraryItems.push(
                <MusicLibraryItem key= {music.id} music={music} history={this.props.history}/>
            );
        }

    });
    console.log(musicLibraryItems, this.state.musicLibraryItems)

    this.setState((prevState) => {
        return {
            musicLibraryItems: musicLibraryItems
            })
        }
    })

}

我认为问题是我没有改变对状态变量的引用,所以它没有意识到状态已被改变。我想知道改变状态变量的最佳方法是什么,以便将musicLibraryItems中的值放入this.state.musicLibraryItems,以便可以在页面上呈现。

2 个答案:

答案 0 :(得分:4)

你可以尝试

<ul>
  { this.filterMusicLibrary() }
</ul>

并更改过滤器以不更改状态

filterMusicLibrary() {
    let musicLibraryItems = [];
    this.state.musicGet.map(music => {
        if(music.title.includes(this.state.title)) {
            console.log(music.title);
            musicLibraryItems.push(
                <MusicLibraryItem key= {music.id} music={music} history={this.props.history}/>
            );
        }

    });
    console.log(musicLibraryItems, this.state.musicLibraryItems);
    return musicLibraryItems;
}

您不应该在州上存储jsx元素。如果您担心重新计算列表,请尝试reselect

答案 1 :(得分:1)

更像是@Murilo已经提到的,对于你不想将它们添加到状态的过滤器,是更加计算的状态...只是添加了一个工作样本

const MusicLibraryItem = ({music}) => {
return <li>{music.title}</li>
}


const lotMusic = [{title: 'Awesome', id: '12121'}, {title: 'Kitchen', id: '121'},
                  {title: 'Golden', id: '21'}, {title: 'Beach', id: '121'}];
class App extends React.Component{

 constructor(){
   super()
   this.state = {musicGet: lotMusic,filterValue: ''} 
   this.updateFilter = this.updateFilter.bind(this);
 }
 
 updateFilter(event) {
    const name = event.target.name;
    this.setState({[name]: event.target.value});
      
 }
 
  filterMusicLibrary(value) {
    let musicLibraryItems = [];
    this.state.musicGet.map(music => {
        if(music.title.includes(value)) {
            console.log(music.title)
            musicLibraryItems.push(
                <MusicLibraryItem key= {music.id} music={music} history={this.props.history}/>
            );
        }

    });
    
    return musicLibraryItems;
   }

   render(){
  
   
      return (
      <div>
      <h2>Test </h2>
      
      <input type="text" onChange={this.updateFilter} 
        name="filterValue"
        value={this.state.filterValue}/>
      
      <ul>{this.filterMusicLibrary(this.state.filterValue)}</ul>
      </div>
      )
   }
}

ReactDOM.render(<App/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>




<div id="app">
</div>