Я столкнулся с проблемой 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 разных действий для каждого города, но это не кажется разумным решением.
Каков наилучший подход для отображения нескольких списков городов на одной странице?
UPDATE
Итак, я изменил редуктор , чтобы он выглядел так:
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)
))
...
}
}
так что каждый массив является неизменным, но опять же он сталкивается с слишком большим количеством перерисовок.
Всем, у кого есть такая проблема, я закончил с этим РЕШЕНИЕ :
В моем редукторе Я отделил каждый предмет для города следующим образом:
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)
...
}
}