В настоящее время я изучаю реакцию и сокращение и наткнулся на проблему, которую не могу понять. Попытка реализовать ту же функциональность как в этой статье: https://medium.com/@yaoxiao1222/implementing-search-filter-a-list-on-redux-react-bb5de8d0a3ad, но даже несмотря на то, что запрос данных от остального api, с которым я работаю, был успешным, я не могу назначить локальное состояние в моем компоненте своему redux-состоянию, чтобы иметь возможность фильтровать мои результаты. Вот мой компонент:
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.info(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
}
}
Любые идеи?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Проблема с вашим кодом заключается в том, что вы не справляетесь, как получить вновь полученные реквизиты для вашего состояния. Это означает, что когда вы получаете данные из своего вызова api, обновляются только реквизиты, а состояние компонента - нет.
Если вы внимательно посмотрите на указанную статью, в методе onInputChange они пересчитывают состояние из реквизитов, тогда как ваш метод updateState фильтрует только локальное состояние.
Установка состояния в конструкторе гарантирует только то, что реквизиты копируются при первоначальном монтировании компонента. В этот момент хранилище содержит только начальное состояние (initialState.posts в вашем коде редуктора). Это цена сохранения как состояния компонента, так и сохранения; вы должны подумать о том, как поддерживать синхронизацию между ними после начальной загрузки.
Одно из решений - обновить состояние в componentWillReceiveProps:
componentWillReceiveProps(nextProps){
const nextFiltered = nextProps.store.posts.filter(your filtering code here);
this.setState({currentlyDisplayed: nextFiltered});
}
Это будет обновлять ваше состояние всякий раз, когда компонент получает новые реквизиты. Обратите внимание, что в response прекращено использование componentWillReceiveProps, и вы должны использовать getDerivedStateToProps, начиная с response 16.3. Обратитесь к здесь для более подробной информации.
Большое спасибо за то, что уделили время чтению моего кода! если я изменю функцию updateSearch для фильтрации по this.props.store.posts.filter (....), вы правы, поскольку я начинаю вводить, функция поиска работает, как ожидалось, но в исходном состоянии список не заполняется . Как мне заполнить список исходными реквизитами, если это не сделано с помощью this.state = {currentDisplayed: this.props.store.posts}?
Отредактировал ответ, чтобы прояснить ситуацию. Честно говоря, я не согласен с оригинальной статьей. Фильтрация с использованием состояния беспорядочная и может выполняться только хранилищем и реквизитом. Подумайте о поиске других методов для достижения вашей цели.
Я считаю, что вам не хватает
stateвthis.currentlyDisplayed.filter. Должен бытьthis.state.currentlyDisplayed.filter()