Поиск / фильтрация списка с помощью response / redux

В настоящее время я изучаю реакцию и сокращение и наткнулся на проблему, которую не могу понять. Попытка реализовать ту же функциональность как в этой статье: 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
   }
 }

Любые идеи?

Я считаю, что вам не хватает state в this.currentlyDisplayed.filter. Должен быть this.state.currentlyDisplayed.filter()

SGhaleb 27.08.2018 11:53
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
1
3 958
1

Ответы 1

Проблема с вашим кодом заключается в том, что вы не справляетесь, как получить вновь полученные реквизиты для вашего состояния. Это означает, что когда вы получаете данные из своего вызова 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}?

Filil Lindbladh 29.08.2018 13:12

Отредактировал ответ, чтобы прояснить ситуацию. Честно говоря, я не согласен с оригинальной статьей. Фильтрация с использованием состояния беспорядочная и может выполняться только хранилищем и реквизитом. Подумайте о поиске других методов для достижения вашей цели.

AlphaD 31.08.2018 05:38

Другие вопросы по теме