React Redux - список элементов по некоторым критериям

Я столкнулся с проблемой React Redux, когда мне нужно, чтобы одна страница отображала несколько списков элементов из одного и того же API. Например, у меня есть конечная точка /items с параметром GET /items?city=Berlin. Мне нужно отобразить списки элементов 5 городов на главной странице.

В настоящее время у меня есть 1 действие для обработки вызова API.

Вот мой reducer.js:

...
const initialState = fromJS({
  ...
  items: [],
  ...
})

export default function reducer (state = initialState, action) {
  ...
  switch (action.type) {
    case fetchItemsByCityRoutine.SUCCESS:
      return state.update('items', (items) => items.push(...action.payload.data))
  ...

} }

saga.js:

function * fetchItemsByCity ({ payload: city }) {
  try {
    yield put(fetchItemsByCityRoutine.request())
    const response = yield call(apiClient.fetchItemsByCity, city)
    response.city = city

    yield put(fetchItemsByCityRoutine.success(response))
  } catch (error) {
    yield put(fetchItemsByCityRoutine.failure(extractErrorMessage(error)))
  } finally {
    yield put(fetchItemsByCityRoutine.fulfill())
  }
}

function * watchItemsByCitySaga () {
  yield takeEvery(fetchItemsByCityRoutine.TRIGGER, fetchItemsByCity)
}

На Домашняя страница я отображаю список таких городов:

const renderCityListSections = () => homepageCityLists.map((city) => <ItemList key = {city.cityName} {...city} />)

Компонент ItemList:

class ItemList extends Component {
  componentDidMount () {
    const { cityName } = this.props
    this.props.fetchItemsByCityRoutine(cityName)
  }

  render () {
    const { items, title } = this.props

    return (
      items.length > 0 &&
      <Wrapper>
        <SlickSlider>
          {items.map((item) => <Item key = {item.id} {...item} />)}
        </SlickSlider>
      </Wrapper>
    )
  }
}

ПРОБЛЕМА заключается в том, что текущее решение заставляет повторно визуализировать представление слишком много раз, потому что каждый раз, когда я получаю новый список для какого-то города, он добавляется в items, поэтому элементы меняются, и это приводит к запуску повторного отображения представления.

У меня была мысль создать 5 разных действий для каждого города, но это не кажется разумным решением.

КАК лучше всего отображать несколько списков городов на одной странице?


ОБНОВИТЬ:

Итак, я изменил редуктор, чтобы он выглядел так:

const initialState = fromJS({
  ...
  items: {
    Miami: [],
    Prague: [],
    Melbourne: [],
    Venice: [],
    Barcelona: [],
  },
  ...
})

export default function reducer (state = initialState, action) {
  switch (action.type) {
    ...
    case fetchItemsByCityRoutine.SUCCESS:
      return state.updateIn(['items', action.payload.city], (list) => (
        list.concat(action.payload.data)
      ))
    ...
  }
}

поэтому каждый массив неизменяем, но опять же приходится слишком много перерисовывать. React Redux - список элементов по некоторым критериям


У всех, у кого есть такая проблема, у меня получился этот РЕШЕНИЕ:

В моем редуктор я развязал каждый элемент для города следующим образом:

const initialState = fromJS({
  ...
  itemsForBerlin: [],
  itemsForAnotherCity: [],
  ...
})

export default function reducer (state = initialState, action) {
  switch (action.type) {
    ...
    case fetchItemsByCityRoutine.SUCCESS:
      return state.set(`itemsFor${action.payload.city}`, action.payload.data)
    ...
  }
}

Как насчет того, чтобы хранить товары в магазинах по городам? state.items[city] = cityItems?

Martin Kadlec 04.05.2018 16:34

@MartinKadlec, вы ведь говорите о редукторе? Если да, то мне кажется, что результат будет таким же, потому что он обновляет items с новой парой ключ => значение, не так ли?

lomboboo 04.05.2018 17:21

Ага, редуктор. При изменении карта предметов будет новой, но все ее участники, кроме нового города, должны по-прежнему иметь исходную ссылку, если все сделано правильно.

Martin Kadlec 04.05.2018 17:38
let items = { Berlin: [1, 2, 3] }; let newItems = { ...items, Prague: [4, 5, 6] }; newItems.Berlin === items.Berlin; // true
Martin Kadlec 04.05.2018 17:40

@MartinKadlec, кажется, я знаю, в чем проблема. Мой проект основан на ImmutableJS, поэтому я думаю, что должен быть какой-то метод для добавления пары ключ / значение в массив items.

lomboboo 04.05.2018 21:21

Он не зря называется неизменяемым :) если вы добавляете элементы в массив, вы должны получить новый массив, иначе он не будет неизменным. К сожалению, мои знания о Immutable.js не так хороши, поскольку мне всегда было слишком утомительно использовать O :) - поэтому я не использовал его в моем примере выше.

Martin Kadlec 04.05.2018 21:28

Вот вам рабочий пример codeandbox.io/s/3vl8vwjmrq

Martin Kadlec 05.05.2018 14:39

@MartinKadlec, спасибо, но большая разница в том, что мне нужно получить все 5 городов одновременно. Вот где возникают проблемы с повторной визуализацией

lomboboo 06.05.2018 12:24

Если вы каждый раз получаете данные по всем городам, вы не можете использовать неизменяемость, чтобы проверять, что наборы элементов одинаковы. Вам нужно будет либо использовать проверку deepEqual, либо передать хеш версии с сервера.

Martin Kadlec 06.05.2018 13:25

@MartinKadlec, ты прав. Вот почему я обновил свой вопрос решением, которое у меня было. Спасибо за помощь!

lomboboo 06.05.2018 13:46
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
10
487
0

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