@rgdzv

Как правильно использовать функцию createSelector (библиотека reselect) с хуком useSelector в приложении React?

Делаю проект на React. Код компонента App:

const App = () => {

  //const { tickets, isFetching, error } = useSelector(({ tickets }) => tickets)  // <- эта строка хорошо отрабатывает

  const { isFetching } = useSelector(({ tickets }) => tickets)
  const tickets = useSelector(sorterSelector)                         //  <- возвращает undefined

  const dispatch = useDispatch()

  const renderedTickets = tickets.map((ticket) => {            //  <- проблема - TypeError: Cannot read property 'map' of undefined
    const src = `http://pics.avs.io/99/36/${ticket.carrier}.png`
    return (
      <Ticket
        key={ticket.price + ticket.segments[0].duration}
        ticket={ticket}
        price={ticket.price}
        src={src}
        segment={ticket.segments}
      />
    )
  }).slice(0,5)

  useEffect(() => {
    dispatch(fetchData())
  }, [])

  return (
    <div className="container">
      <Header />
      <div className="content">
        <Filter />
        <div className="content__item">
          <div className="content__item__sorting">
            <Sorter/>
          </div>
          {isFetching 
            ? 
              <img src={preloader} alt="preloader"/>
            : 
              <div className="content__item__tickets">
                {renderedTickets}
              </div>
          }
        </div>
      </div>
    </div>
  )
}


Код для селектора:

const allTickets = state => state.tickets
const selected = state => state.sorter.selected

export const sorterSelector = createSelector(
  [allTickets, selected],
  (tickets, selec) => {                                         // <- tickets - пустой массив
    if (tickets.isFetching || tickets.error) {
      return []
    }
    if (selec === "Самый дешевый") {
      [...tickets.tickets].sort((a, b) => {
        return a.price - b.price
      })
    } else {
      [...tickets.tickets].sort((a, b) => {
        return (a.segments[0].duration + a.segments[1].duration) - (b.segments[0].duration + b.segments[1].duration)
      })
    }
  }
)


Первая закомментированная строка в компоненте App (где я деструктурирую объект) работает хорошо: я получаю билеты с сервера и отображаю их в компоненте. Но мне необходимо добавить сайд-эффекты в массив билетов (сортировка, фильтрация), поэтому я решил использовать селектор.

Однако, при использовании такой записиconst tickets = useSelector(sorterSelector), селектор возвращает undefined (ошибка TypeError: Cannot read property 'map' of undefined). При данной записи и логике, которую я описал в sorterSelector, я даже не вижу, что функция fetchData в useEffect компонента App запускается.

Как решить эту проблему?
Использование записи
const tickets = useSelector(state => sorterSelector(state))
также не помогает. Функция fetchData не запускается, селектор остается undefined.
  • Вопрос задан
  • 182 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы