Вспомогательная функция Redux для проверки наличия значения в хранилище

#javascript #reactjs #redux #react-redux

#javascript #reactjs #redux #реагировать-redux

Вопрос:

У меня есть панель фильтров, где пользователь может выбирать различные цветовые фильтры:

 // ColorButton.jsx
function ColorButton({ color }) {

 const handleFilterSelected = ({ id }) => {
    dispatch(applyFilter({ type: "colors", value: id }));
  };

  return (
    <div className="color-button" onClick={() => handleFilterSelected(color)}>
      {isFilterSelected({ type: "colors", value: color.id }) ? "yay" : "nay"}
    </div>
  );
}
 

Выбранные фильтры сохраняются в хранилище redux, и isFilterSelect функция выглядит следующим образом:

 // redux/utils/filter.utils.js
export const isFilterSelected = ({ type, value }) => {
  const {
    filters: { applied }
  } = store.getState();

  return applied
    .filter((f) => f.type === type)
    .map((f) => f.value)
    .includes(value);
};

 

Проблема в том, что проверка выполняется до добавления выбранного фильтра в applied массив.

В качестве более общего вопроса — это вообще хорошая идея иметь «вспомогательные» функции, которые зависят от хранилища redux?

Ответ №1:

Ваша вспомогательная функция должна быть записана как селектор, который получает текущее состояние, и вы должны использовать useSelector его вместо store.getState ручного, так как это обновит ваш компонент при изменении значения селектора.

 function ColorButton({ color }) {
  const isSelected = useSelector(state => isFilterSelected(state, { type: "colors", value: color.id }));
  return (
    <div className="color-button">
      {isSelected ? "yay" : "nay"}
    </div>
  );
}


// redux/utils/filter.utils.js
export const isFilterSelected = (state, { type, value }) => {
  return state.filters.applied
    .filter((f) => f.type === type)
    .map((f) => f.value)
    .includes(value);
};