Next.js中如何用URL参数结合localeCompare过滤数组对象?
问题排查与修正:用自定义localeCompare工具函数过滤数组
我在Next.js项目里用JavaScript开发,需要通过URL获取的genre参数,结合自定义的比较逻辑(基于localeCompare实现不区分大小写的匹配),过滤数组中name属性和genre匹配的对象。目前能正常拿到URL里的genre参数,硬编码匹配值的过滤逻辑也没问题,但换成自定义比较函数和genre变量后就出问题了,下面是问题分析和修正方案。
问题根源
- filter方法传参错误:
filter需要接收一个返回布尔值的回调函数,但你现在直接调用了useLocalCompare(placeholder.name, genre),这会立刻执行函数并返回字符串"True"/"False",而不是给filter传一个回调。 - 比较函数返回值错误:你的
useLocalCompare返回的是字符串"True"/"False",但filter只认布尔值true/false。字符串在JS里会被当成真值,导致所有数组项都被保留下来。 - 没必要做成React钩子:这个比较函数没有用到React的状态、副作用等钩子特性,做成普通工具函数就行,叫
useLocalCompare反而容易混淆。
修正步骤
1. 重构比较函数为普通工具函数
把返回值改成布尔值,同时处理空值避免报错:
// 重命名为更语义化的名字,比如localCompareEqual export default function localCompareEqual(s1, s2) { // 处理空值,防止s1或s2为undefined/null时报错 if (!s1 || !s2) return false; // sensitivity: "base" 表示忽略大小写、重音,只比较基础字符 return s1.localeCompare(s2, undefined, { sensitivity: "base" }) === 0; }
2. 修正filter的回调逻辑
给filter传一个回调函数,遍历数组时对每一项调用比较函数:
import localCompareEqual from './path-to-your-file'; // 先判断数组和genre参数都不为空,再执行过滤 let filteredArray = []; if (flatarrayofvalues && genre) { filteredArray = flatarrayofvalues.filter(item => localCompareEqual(item.name, genre) ); }
3. 边界情况处理(可选但推荐)
如果flatarrayofvalues可能是null或undefined,可以用可选链简化:
const filteredArray = flatarrayofvalues?.filter(item => localCompareEqual(item.name, genre) ) || [];
完整示例代码
工具函数文件(localCompareEqual.js)
export default function localCompareEqual(s1, s2) { if (!s1 || !s2) return false; return s1.localeCompare(s2, undefined, { sensitivity: "base" }) === 0; }
组件中的过滤逻辑
import localCompareEqual from './localCompareEqual'; import { useRouter } from 'next/router'; export default function GenreFilterComponent() { const router = useRouter(); // 从URL查询参数获取genre const { genre } = router.query; // 你的数组数据 const flatarrayofvalues = [ { id: 28, name: 'Action' }, { id: 12, name: 'Adventure' }, { id: 16, name: 'Animation' }, { id: 35, name: 'Comedy' }, { id: 80, name: 'Crime' }, { id: 99, name: 'Documentary' }, { id: 18, name: 'Drama' }, { id: 10751, name: 'Family' }, { id: 14, name: 'Fantasy' }, { id: 36, name: 'History' }, { id: 27, name: 'Horror' }, { id: 10402, name: 'Music' }, { id: 9648, name: 'Mystery' }, { id: 10749, name: 'Romance' }, { id: 878, name: 'Science Fiction' }, { id: 10770, name: 'TV Movie' }, { id: 53, name: 'Thriller' }, { id: 10752, name: 'War' }, { id: 37, name: 'Western' }, { name: 'Trending' }, { name: 'Top Rated' } ]; // 执行过滤 const filteredArray = flatarrayofvalues?.filter(item => localCompareEqual(item.name, genre) ) || []; return ( <div> <h2>过滤后的类型:</h2> {filteredArray.map(item => ( <div key={item.id || item.name}>{item.name}</div> ))} </div> ); }
内容的提问来源于stack exchange,提问作者Time2learn
相关产品推荐
相关产品推荐

