【问题标题】:searching/filtering a list with react/redux使用 react/redux 搜索/过滤列表
【发布时间】:2019-02-01 19:34:46
【问题描述】:

我目前正在学习 react 和 redux,但偶然发现了一个我无法真正理解的问题。尝试实现相同的功能 如本文所示:https://medium.com/@yaoxiao1222/implementing-search-filter-a-list-on-redux-react-bb5de8d0a3ad 但即使来自我正在使用的其他 api 的数据请求成功,我也无法将组件中的本地状态分配给我的 redux-state,以便能够过滤我的结果。这是我的组件:

import React from 'react'
import {connect} from 'react-redux'
import {bindActionCreators} from 'redux'
import * as fetchActions from '../../actions/fetchActions'
import Stafflist from './Stafflist'

class AboutPage extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      search: '',
      currentlyDisplayed: this.props.store.posts
    }
    this.updateSearch = this.updateSearch.bind(this)
  }
  updateSearch(event) {
    let newlyDisplayed = this.state.currentlyDisplayed.filter(
      (post) => { 
        return (
          post.name.toLowerCase().indexOf(this.state.search.toLowerCase()) !== -1
          || post.role.toLowerCase().indexOf(this.state.search.toLowerCase()) !== -1
        )}
    )
    console.log(newlyDisplayed)
    this.setState({
      search: event.target.value.substr(0, 20),
      currentlyDisplayed: newlyDisplayed
    })
  }
  render() {
     return (
      <div className="about-page">
        <h1>About</h1>
        <input type="text"
          value={this.state.search}
          onChange={this.updateSearch}
        />
        //component for rendering my list of posts.
        <Stafflist posts={this.state.currentlyDisplayed} />
      </div>
     )
  }
}
// this is here i assign my api data to this.props.store.posts
function mapStateToProps(state, ownProps) {
  return {
    store: state
  }
}

function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators(fetchActions, dispatch)
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(AboutPage)

比较我如何将我的商店状态分配给我的本地组件与它在文章中的工作方式,它似乎以相同的方式完成。我的:

this.state = {
   search: '',
   currentlyDisplayed: this.props.store.posts
}

文章:

this.state = {
   searchTerm: '',
   currentlyDisplayed: this.props.people
}

在 react devtools 中,我可以看到我的数据,因为它应该在商店中,但是将它分配给组件中的本地状态以执行过滤是行不通的,我真的不知道如何调试这个。我在本地组件中的状态只是说

 State
 currentlyDisplayed: Array[0]
 Empty array

如果我改变了

<Stafflist posts={this.state.currentlyDisplayed} /> 

<Stafflist posts={this.props.store.posts} /> 

列表按原样呈现:)

减速机:

 import * as types from '../actions/actionTypes'
 import initialState from './initialState'


 export default function postReducer(state = initialState.posts, action) {
   switch(action.type) {
   case types.FETCH_POSTS_SUCCESS:
     return action.posts.data.map(post => {
       return {
         id: post.id,
         name: post.acf.name,
         role: post.acf.role
       }
     })     
   default:
     return state
   }
 }

有什么想法吗?

【问题讨论】:

  • 我相信您在this.currentlyDisplayed.filter 中缺少state。应该是this.state.currentlyDisplayed.filter()

标签: javascript reactjs search filter redux


【解决方案1】:

您的代码的问题是您没有处理如何将新收到的道具获取到您的状态。这意味着当您从 api 调用接收数据时,只会更新 props,而不会更新组件状态。

如果您仔细查看引用的文章,在 onInputChange 方法中,它们会根据道具重新计算状态,而您的 updateState 方法仅从本地状态过滤。

在构造函数中设置状态只能确保在组件的初始挂载时复制道具。在那个时间点,store 只包含初始状态(你的 reducer 代码中的 initialState.posts)。这是同时保持组件状态和存储的代价;您必须考虑在初始加载后如何使两者保持同步。

一种解决方案是更新 componentWillReceiveProps 中的状态:

componentWillReceiveProps(nextProps){
  const nextFiltered = nextProps.store.posts.filter(your filtering code here);
  this.setState({currentlyDisplayed: nextFiltered});
}

这将在组件收到新道具时更新您的状态。注意 react 已经淘汰了 componentWillReceiveProps,你应该从 react 16.3 开始使用 getDerivedStateToProps。详情请参考here

【讨论】:

  • 非常感谢您花时间阅读我的代码!如果我更改 updateSearch 功能以过滤 this.props.store.posts.filter(....) 你是对的,因为我开始输入搜索功能按预期工作,但在初始状态下未填充列表.如果 this.state = {currentlyDisplayed: this.props.store.posts} 没有完成,我应该如何用初始道具填充列表?
  • 编辑了答案以澄清问题。老实说,我不同意原始文章。使用 state 进行过滤很麻烦,可以单独通过 store 和 props 来完成。考虑为您的目标研究其他方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-24
  • 2018-09-09
  • 1970-01-01
  • 1970-01-01
  • 2018-03-30
  • 1970-01-01
  • 2017-09-24
相关资源
最近更新 更多