(React Problem)
Let’s say we have array of objects like this:
const books = [
{
author: "Marcel Proust",
title: "In Search of Lost Time",
pageNumber: 123,
},
{
author: "James Joyce",
title: "Ulysses",
pageNumber: 123,
},
{
author: "Miguel de Cervantes",
title: "Quixote",
pageNumber: 123,
},
{
author: "Herman Melville",
title: "Moby Dick",
pageNumber: 123,
},
{
author: "William Shakespeare",
title: "Hamlet",
pageNumber: 123,
},
];
Also we have an input and state like this:
const [text, setText] = useState("");
const handleOnChange = (event) => {
setText(event.target.value);
};
<input value={text} onChange={handleOnChange} />;
Now, I would like to filter this array depends on input text, and [author | title] property.
Example:
If user types ‘M’, the array of object should look like this:
const books = [
{
author: "Marcel Proust",
title: "In Search of Lost Time",
pageNumber: 123,
},
{
author: "Miguel de Cervantes",
title: "Quixote",
pageNumber: 123,
},
{
author: "Herman Melville",
title: "Moby Dick",
pageNumber: 123,
},
];
…because the author or title start with letter M.
>Solution :
Every time the input text changes you can use Array.prototype.filter to filter out the books where the title or the author contains the input text.
Note: I’ve used String.prototype.includes to calculate the matches but you can use other String methods as well, like String.prototype.startsWith.
const books = [
{ author: "Marcel Proust", title: "In Search of Lost Time", pageNumber: 123 },
{ author: "James Joyce", title: "Ulysses", pageNumber: 123 },
{ author: "Miguel de Cervantes", title: "Quixote", pageNumber: 123 },
{ author: "Herman Melville", title: "Moby Dick", pageNumber: 123 },
{ author: "William Shakespeare", title: "Hamlet", pageNumber: 123 },
];
const App = () => {
const [searchText, setSearchText] = React.useState("");
const filteredBooks = books.filter(
({ author, title }) =>
author.toLowerCase().includes(searchText.toLowerCase()) ||
title.toLowerCase().includes(searchText.toLowerCase())
);
return (
<div>
<input
type="text"
value={searchText}
onChange={({ target }) => setSearchText(target.value)}
/>
<ul>
{filteredBooks.map(({ author, title }) => (
<li key={title}>
<strong>{title}</strong> by {author}
</li>
))}
</ul>
</div>
);
};
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div id="root"></div>