When creating a React application for filtering properties in a marketplace, you might find yourself struggling to implement filtering logic that can handle multiple conditions. Whether the user wants to filter by the type of property, type of operation (rent/sell), or price range, managing these filters efficiently can be challenging.
In this blog post, we’ll dive into a sample React application and break down how to create a multi-conditional filtering logic. The main components in question are SearchContext.jsx
and PropListContainer.jsx
.
Let’s dissect the code and walk through the solution.
SearchContext.jsx
First, let’s take a look at SearchContext.jsx
. This component is responsible for managing the global state of our search filters using React’s Context API.
import React, { createContext, useState, useContext } from "react"; // Create a Context for the search filters const SearchContext = createContext(); export const SearchProvider = ({ children }) => { const [filters, setFilters] = useState({ type: "", operation: "", minPrice: 0, maxPrice: Infinity }); return ( <SearchContext.Provider value={{ filters, setFilters }}> {children} </SearchContext.Provider> ); }; export const useSearch = () => useContext(SearchContext);
In this component, we create a context and provide an initial state for our filters. This state includes properties for filtering by type, operation, and price range. The SearchProvider
component wraps our children components, allowing them to access and modify the filter state.
PropListContainer.jsx
Next, let’s move on to the PropListContainer.jsx
component, where the filtering logic is implemented.
import React from "react"; import { useSearch } from "./SearchContext"; import PropCard from "./PropCard"; const properties = [ // Array of property objects for demonstration purposes // Each object contains fields like type, operation, price, etc. ]; const PropListContainer = () => { const { filters } = useSearch(); const filteredProperties = properties.filter(property => { const matchType = filters.type ? property.type === filters.type : true; const matchOperation = filters.operation ? property.operation === filters.operation : true; const matchMinPrice = property.price >= filters.minPrice; const matchMaxPrice = property.price <= filters.maxPrice; return matchType && matchOperation && matchMinPrice && matchMaxPrice; }); return ( <div> {filteredProperties.map(property => ( <PropCard key={property.id} property={property} /> ))} </div> ); }; export default PropListContainer;
The key part of this component is the filter
method applied to the properties
array. Here’s a breakdown of the logic:
- matchType: This checks if a type filter is set. If so, it matches the property’s type with the filter. If the filter is not set, it defaults to true, meaning it doesn’t exclude any properties based on type.
- matchOperation: Similar to
matchType
, this checks the operation filter.
- matchMinPrice: This ensures that the property’s price is greater than or equal to the minimum price set in the filters.
- matchMaxPrice: This ensures that the property’s price is less than or equal to the maximum price set in the filters.
By combining these conditions with logical AND (&&
), we ensure that only properties matching all the selected filters are included in the final result.
Handling User Input
To make the filters work dynamically based on user input, you’ll need a form or input elements that allow users to set these filters and then update the context state accordingly. Here’s a quick example of how you might set up such a form:
import React from "react"; import { useSearch } from "./SearchContext"; const FilterForm = () => { const { filters, setFilters } = useSearch(); const handleInputChange = (e) => { const { name, value } = e.target; setFilters({ ...filters, [name]: value }); }; return ( <form> <label> Type: <input type="text" name="type" value={filters.type} onChange={handleInputChange} /> </label> <br /> <label> Operation: <input type="text" name="operation" value={filters.operation} onChange={handleInputChange} /> </label> <br /> <label> Min Price: <input type="number" name="minPrice" value={filters.minPrice} onChange={handleInputChange} /> </label> <br /> <label> Max Price: <input type="number" name="maxPrice" value={filters.maxPrice} onChange={handleInputChange} /> </label> </form> ); }; export default FilterForm;
This form uses controlled components to capture user input and update the context’s filter state. Whenever an input value changes, the handleInputChange
function updates the corresponding filter value in the state.
By integrating this form into your component tree, you allow users to dynamically adjust filters, which in turn updates the filtered property list in PropListContainer
.
In summary, implementing multi-conditional filters in your React marketplace app involves setting up a global filter state using Context, applying multiple conditions in your filtering logic, and creating user inputs to dynamically update the filters. With these pieces in place, you can create a flexible and responsive filtering system for your property listings.
Leave a Reply