#reactjs #filter #react-hooks
#reactjs #Фильтр #реагирующие хуки
Вопрос:
У меня есть таблица транзакций, которая содержит некоторые данные. Я пытаюсь создать фильтр на стороне клиента при замене ввода поиска.
Сначала это работает, при следующем событии onChange фильтруются ранее отфильтрованные данные, а не исходные данные.
Как я могу сделать так, чтобы он всегда фильтровал начальное состояние при каждом событии onChange?
Если есть лучший подход для этого, пожалуйста, скажите мне
//Table
const [transactions, setTransactions] = useReducer(
transactionsReducer,
fetchTransactions()
)
//Reducer
const transactionsReducer = (state, action) => {
switch (action.type) {
case 'filter':
return action.transactions.filter(item =>
item.description.includes(action.searchTerm)
)
default:
return state
}
}
//Search component (it receives setTransactions function as a prop)
const Search = ({ setTransactions }) => {
const handleChange = event => {
setTransactions({
type: 'filter',
searchTerm: event.target.value
})
}
return (
<form>
<Input
type="text"
name="search"
placeholder="search"
onChange={handleChange}
/>
</form>
)
}
Комментарии:
1. Ваш редуктор должен возвращать как исходные данные, так и отфильтрованные данные. В настоящее время редуктор возвращает только отфильтрованные данные, поэтому при следующем
onChange
вызове sofilter
будет работать с ранее отфильтрованными данными. Или вы можете использовать другой подход, выполнив фильтрацию внутриonChange
и установив отфильтрованное значение в другом локальном состоянии.2. Я пытаюсь не использовать для этого другое состояние. «Ваш редуктор должен возвращать как исходные, так и отфильтрованные данные», как именно я могу это сделать?
3. В принципе, ваше начальное состояние для
useReducer
будет иметь форму, подобную{transaction: fetchTransactions(), filtered: []}
. Когда вы отправляетеfilter
тип, ваш редуктор должен фильтроватьfiltered = yourFilterFunction(state.transactions)
и возвращать его как{...state, filter: filtered}
. И вы можете получить доступ к отфильтрованным транзакциям какtransactions.filtered
внутри вашего компонента
Ответ №1:
Я передал транзакции в компонент поиска из fetchTransactions() следующим образом
<Search
setTransactions={setTransactions}
transactions={fetchTransactions()}
/>
а затем передайте эти транзакции моему редуктору в качестве действия:
const handleChange = event => {
setTransactions({
type: 'filter',
transactions, //like this
searchTerm: event.target.value
})
}
и отфильтруйте эти транзакции в моем редукторе:
const transactionsReducer = (state, action) => {
switch (action.type) {
case 'filter':
return action.transactions.filter(item =>
item.description.includes(action.searchTerm)
)
default:
return state
}
}
и это работает нормально. Если есть лучшие подходы к этому, пожалуйста, дайте мне знать