Reputation: 11
A react newbie here.
I have a functioning search bar by which it is possible to search and go to the url of the item in the list. This is achieved by useNavigate. I have two problems with this.
What I want to do with it:
My Problems:
Below is my code.
-SearchBar component:
import styled from "styled-components";
import { HiOutlineSearch } from "react-icons/hi";
import { useEffect, useRef, useState } from "react";
import { useArticle } from "../contexts/ArticleProvider";
import SearchList from "./SearchList";
const FormContainer = styled.div`
position: relative;
display: flex;
flex-direction: column;
align-items: center;
`;
const Form = styled.form`
display: flex;
align-items: center;
background-color: #fff;
border: 1px solid #ccc;
border-radius: 4px;
overflow: hidden;
max-width: 600px; // Adjust based on layout
width: 100%;
`;
const Input = styled.input`
flex: 1;
border: none;
padding: 8px 12px;
font-size: 16px;
&:focus {
outline: none;
}
`;
const Button = styled.button`
background-color: #fff;
border: none;
padding: 8px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
&:hover {
background-color: #f0f0f0;
}
svg {
width: 20px;
height: 20px;
}
`;
function SearchBar() {
const [input, setInput] = useState("");
const [filteredArticles, setFilteredArticles] = useState([]);
const { data } = useArticle();
// Fetch data according to the input
useEffect(() => {
if (input) {
const results = data.filter(
(article) =>
article.title.toLowerCase().includes(input.toLowerCase()) ||
article.category.toLowerCase().includes(input.toLowerCase()) ||
article.product.toLowerCase().includes(input.toLowerCase())
);
setFilteredArticles(results.slice(0, 5));
} else {
setFilteredArticles(data);
}
}, [input, data]);
function handleChange(value) {
setInput(value);
}
// Click outside to close the SearchList
// with this, search bar doesn't work, and SearchList closes. When I delete this, search bar works.
let searchRef = useRef();
useEffect(() => {
let handler = (e) => {
if (!searchRef.current.contains(e.target)) {
setInput("");
}
};
document.addEventListener("mousedown", handler);
return () => {
document.removeEventListener("mousedown", handler);
};
});
return (
<FormContainer>
<Form>
<Input
placeholder="Ürün, kategori ya da marka arayın"
value={input}
onChange={(e) => handleChange(e.target.value)}
ref={searchRef}
/>
<Button>
<HiOutlineSearch />
</Button>
</Form>
{input && <SearchList articles={filteredArticles} />}
</FormContainer>
);
}
export default SearchBar;
-SearchList component
import { useNavigate } from "react-router-dom";
import styled from "styled-components";
const ArticlesList = styled.div`
position: absolute;
top: 100%; // Align right below the search bar
left: 0;
right: 0;
z-index: 1000;
background-color: #fff;
border: 1px solid #ccc;
border-radius: 4px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
max-width: 600px; // Adjust based on layout
margin: 0 auto; // Center the list
`;
const ArticleItem = styled.div`
padding: 15px;
border-bottom: 1px solid #eee;
transition: background-color 0.3s ease;
&:hover {
background-color: #f9f9f9;
cursor: pointer;
}
h3 {
margin: 0 0 10px 0;
font-size: 18px;
color: #333;
}
p {
margin: 5px 0;
color: #666;
}
`;
function ArticleList({ articles }) {
const navigate = useNavigate();
function handleNavigate(id) {
navigate(`/makale/${id}`);
}
return (
<ArticlesList>
{articles.map((article) => (
<ArticleItem
key={article.id}
onClick={() => handleNavigate(article.id)}
>
<p>{article.product}</p>
</ArticleItem>
))}
</ArticlesList>
);
}
export default ArticleList;
I tried window.location.href which cause full page reload. Instead of navigate function, I tried NavLink hoping it could refresh the component only, it didn't work either.
Upvotes: 1
Views: 29