基于Supabase与Next.js实现房产列表筛选按钮的技术求助
基于Supabase与Next.js实现房产列表筛选按钮的技术求助
嘿,刚接触Next.js和Web开发的话,能搭到这个框架已经很棒啦!看你给出的代码,已经有了filter状态,应该是想给房产列表加筛选功能对吧?我来帮你梳理下实现思路和代码完善方案~
方案一:后端筛选(推荐,数据量大时更高效)
直接让Supabase根据筛选条件返回对应数据,避免前端加载全部数据再过滤,性能更优:
const Properties = () => { const [user, setUser] = useState(); const [filter, setFilter] = useState(''); const [properties, setProperties] = useState<Property[]>([]); useEffect (() => { // 检查用户登录状态,未登录则跳转登录页 const checkAuthAndFetchProperties = async () => { const { data: { user } } = await supabase.auth.getUser(); if (!user) { redirect('/login'); return; } setUser(user); // 根据筛选条件构建Supabase查询语句 let query = supabase.from('properties').select('*'); // 按空置状态筛选的核心逻辑,可按需扩展 if (filter === 'vacant') { query = query.eq('vacant', true); } else if (filter === 'occupied') { query = query.eq('vacant', false); } // 示例:添加租金范围筛选 // if (filter.rentMin) query = query.gte('rent_per_month', filter.rentMin); const { data, error } = await query; if (error) { console.error('加载房产数据失败:', error); // 这里可以加用户友好提示,比如Toast组件 return; } setProperties(data as Property[]); }; checkAuthAndFetchProperties(); }, [filter]); // 依赖filter,筛选条件变化时自动重新查询 return ( <div className="properties-page"> <Sidebar /> <div className="main-content"> <PageHeader title={pageTitle} /> {/* 筛选按钮组 */} <div className="filter-controls"> <button onClick={() => setFilter('')} className={filter === '' ? 'active-filter' : ''} > 全部房源 </button> <button onClick={() => setFilter('vacant')} className={filter === 'vacant' ? 'active-filter' : ''} > 空置房源 </button> <button onClick={() => setFilter('occupied')} className={filter === 'occupied' ? 'active-filter' : ''} > 已出租房源 </button> </div> <PropertyList properties={properties} /> </div> </div> ); }; export default Properties;
方案二:前端筛选(适合数据量小的场景)
如果你的房产数据量不大,也可以先加载全部数据,再在前端用数组方法过滤,减少后端请求次数:
import { useEffect, useState, useMemo } from 'react'; // 其他导入保持不变 const Properties = () => { const [user, setUser] = useState(); const [filter, setFilter] = useState(''); const [allProperties, setAllProperties] = useState<Property[]>([]); useEffect (() => { // 仅在组件挂载时加载全部数据 const checkAuthAndFetchAllProperties = async () => { const { data: { user } } = await supabase.auth.getUser(); if (!user) { redirect('/login'); return; } setUser(user); const { data, error } = await supabase.from('properties').select('*'); if (error) { console.error('加载房产数据失败:', error); return; } setAllProperties(data as Property[]); }; checkAuthAndFetchAllProperties(); }, []); // 用useMemo避免不必要的重渲染,仅当数据或筛选条件变化时计算 const filteredProperties = useMemo(() => { if (!filter) return allProperties; switch(filter) { case 'vacant': return allProperties.filter(p => p.vacant); case 'occupied': return allProperties.filter(p => !p.vacant); // 示例:按高租金筛选 // case 'high-rent': // return allProperties.filter(p => p.rent_per_month > 2000); default: return allProperties; } }, [allProperties, filter]); return ( <div className="properties-page"> <Sidebar /> <div className="main-content"> <PageHeader title={pageTitle} /> {/* 筛选按钮组和方案一一致 */} <div className="filter-controls"> {/* 按钮代码省略 */} </div> <PropertyList properties={filteredProperties} /> </div> </div> ); };
实用小建议
- 给筛选按钮加
active-filter类,用CSS高亮当前选中的筛选条件,提升用户体验 - 如果需要更复杂的筛选(比如地址搜索、租金滑块),可以把
filter改成对象类型,比如const [filter, setFilter] = useState({ vacant: null, minRent: 0 }),再对应调整查询逻辑 - 错误处理别只停留在控制台打印,给用户显示友好的提示信息会更专业
备注:内容来源于stack exchange,提问作者Harvey
相关产品推荐
相关产品推荐

