#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);
};