On my ecommerce project I wanna impelement a search bar where you can search products by name through drf api, I installed django_filters and created a class like so:
class ProductFilter(generics.ListCreateAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
filter_backends = [filters.SearchFilter]
search_fields = ['^name']
I tested the endpoint and it works but I don't know how to make it work on the frontend part with react, I have the saerchbar in the header like so:
<Form className="d-flex">
<Form.Control
type="search"
placeholder="Search"
className="me-2"
aria-label="Search"
/>
<Button variant="outline-success">Search</Button>
</Form>
Using axios for api calls, I have no idea how to set this up and if I need reducers, actions, store too
CodePudding user response:
I think you can create a function which will make an api call when user enters any text in the input. Also, debounce it to avoid frequent api calls.
import React, { useCallback } from "react";
// Debounce to avoid frequent api calls
export const debounce = (func, waitFor) => {
let timeout = null;
const debounced = (...args) => {
if (timeout !== null) {
clearTimeout(timeout);
timeout = null;
}
timeout = setTimeout(() => func(...args), waitFor);
};
return debounced;
};
const TestComponent = () => {
// debounce the function so that we send api calls once user stops typing
const searchSomething = useCallback(
debounce(async (value) => {
try {
// Make your api call using whichever library you are using
// let response = await fetch(`${YOUR_SERVER_URL}/search?query=${value}`);
let response = axios.get(`${YOUR_SERVER_URL}/search?query=${value}`)
console.log(response);
} catch (error) {
console.log(error);
}
}, 500),
[]
);
return (
<Form className="d-flex">
<Form.Control
type="search"
placeholder="Search"
className="me-2"
aria-label="Search"
onChange={(e) => {
searchSomething(e.target.value);
}}
/>
<Button variant="outline-success">Search</Button>
</Form>
);
};
export default TestComponent;
CodePudding user response:
Your axios
call should end up something like this:
axios({
method: 'post',
url: '/login', // replace with your endpoint URL
data: {
searchField.name: searchField.value,
}
});
with searchField.name being whatever field name Django is expecting to receive on the back end (it looks like it's name
here), and searchField.value being the value of the search field.