Reputation: 225
I have a function to filter an array of todos. The array is filtered correctly but when I type some thing else it removes other array elements and doesn't go back.
I've seen a few solutions, but they say "you have to write code in the render function" and I don't use this method because I render the array elsewhere with the help of props. filteredTodos
has all local storage data.
How can I filter this data without losing data?
// *** Form.js ***
const filterTodos = (e) => {
const filtTod = filteredTodos.filter((todo) => {
return todo.text.toLowerCase().indexOf(e.target.value.toLowerCase()) !== -1
});
setFilteredTodos([...filtTod]);
};
// it's my render place *** TodoList.js ***
return (
<div className="todo-container">
<ul className="todo-list">
{filteredTodos.map((todo) => {
return (
<Todo
id={todo.id}
key={todo.id}
text={todo.text}
completed={todo.completed}
setTodos={setTodos}
todos={todos}
/>
)
})}
</ul>
</div>
);
const [inputText, setInputText] = useState("");
const [todos, setTodos] = useState([]); // Todos is all array items.
const [status, setStatus] = useState("all");
const [filteredTodos, setFilteredTodos] = useState([]); // the state is for my filter list
Upvotes: 1
Views: 2096
Reputation: 57394
The idea with filtering data like an array of todos is to maintain a consistent "reference" or "source" array that represents all of the todos that exist in your app. This reference array may change when the user adds or removes a todo item, and may be persisted to the backend (or local storage, in your case) in some capacity or other. This array is the source of truth.
When a user enters a search/filtering term, filter on the reference/source array of all todos every time rather than the already-filtered result set.
In your code, todos
represents the source array and filteredTodos
represents the results of a single search. By using filteredTodos.filter
, the results either keep diminishing after each filtering query, or there never were any results to work with to begin with -- either way, it's incorrect.
Think of filteredTodos
as a temporary snapshot of todos
used to show a subset view of todos to match the user's search term.
The fix is to use todos.filter
rather than filteredTodos.filter
so that you're always searching on the full data set.
Upvotes: 1