英文:
Preserving Previous Filters and Adding New Filters in React/Next.js Data Filtering
问题
我目前正在尝试使用React/Next.js来过滤数据,但我遇到了一个问题。当我设置一个新的过滤器时,之前的过滤器被删除了。例如,如果用户执行搜索,它可以正常工作,但标签过滤器从URL中删除了。
我想要的是保留先前的过滤器,并在已经设置的情况下添加或更新新的过滤器。例如,URL可以是:localhost:3000/?search=text&tag=food。
我的搜索输入代码:
import React, { useState } from "react";
import { XMarkIcon } from "@heroicons/react/24/outline";
export default function Search({ useRouter, search }) {
const [searchQuery, setSearchQuery] = useState(search);
const { push } = useRouter();
const handleInputChange = (e) => {
setSearchQuery(e.target.value);
push("/?search=" + e.target.value);
};
const cleanSearch = (e) => {
e.preventDefault();
setSearchQuery("");
push("/?search=");
};
return (
// 其他部分...
<input
type="search"
id="default-search"
className="block w-full rounded-lg border border-slate-300 bg-slate-50 p-4 pl-10 text-sm placeholder-slate-400 focus:border-blue-500 focus:ring-blue-500"
placeholder="Search AI tool or category"
required
value={searchQuery}
onChange={handleInputChange}
/>
// 其他部分...
);
}
我的过滤器组件:
"use client";
import React from "react";
import Search from "../common/search";
import Selector from "../common/selector";
import { useRouter } from "next/navigation";
export default function Filters({ tags, prices, search }) {
return (
<div className="mb-5 flex w-full grid-cols-4 flex-col gap-3 text-center text-base font-medium text-slate-700 md:grid">
<Search
className="col-span-2 w-full"
search={search}
useRouter={useRouter}
/>
<Selector label="Category" data={tags} useRouter={useRouter} />
<Selector label="Price" data={prices} useRouter={useRouter} />
</div>
);
}
在搜索组件中,我尝试添加的而不是直接推送的内容是:
const handleInputChange = (e) => {
setSearchQuery(e.target.value);
updateQueryParams({ search: e.target.value });
};
const updateQueryParams = (newParams) => {
const existingQueryParams = { ...router.query };
const updatedQueryParams = { ...existingQueryParams, ...newParams };
let queryString = router.pathname; // 初始化为 router.pathname
const queryKeys = Object.keys(updatedQueryParams);
if (queryKeys.length > 0) {
const queryArray = queryKeys.map((key) => `${key}=${updatedQueryParams[key]}`);
queryString += `?${queryArray.join("&")}`;
}
router.push(queryString);
};
英文:
I'm currently trying to filter data using React/Next.js, but I'm facing an issue. When I set a new filter, the previous ones are being removed. For example, if the user performs a search, it works fine, but the tag filters are removed from the URL.
What I would like is to preserve the previous filters and add or update a new filter if it's already set up. For example, the URL could be: localhost:3000/?search=text&tag=food.
My search input code:
import React, { useState } from "react";
import { XMarkIcon } from "@heroicons/react/24/outline";
export default function Search({ useRouter, search }) {
const [searchQuery, setSearchQuery] = useState(search);
const { push } = useRouter();
const handleInputChange = (e) => {
setSearchQuery(e.target.value);
push("/?search=" + e.target.value);
};
const cleanSearch = (e) => {
e.preventDefault();
setSearchQuery("");
push("/?search=");
};
return (..................
<input
type="search"
id="default-search"
className="block w-full rounded-lg border border-slate-300 bg-slate-50 p-4 pl-10 text-sm placeholder-slate-400 focus:border-blue-500 focus:ring-blue-500"
placeholder="Search AI tool or category"
required
value={searchQuery}
onChange={handleInputChange}
/>
................);}
My filter component :
"use client";
import React from "react";
import Search from "../common/search";
import Selector from "../common/selector";
import { useRouter } from "next/navigation";
export default function Filters({ tags, prices, search }) {
return (
<div className="mb-5 flex w-full grid-cols-4 flex-col gap-3 text-center text-base font-medium text-slate-700 md:grid">
<Search
className="col-span-2 w-full"
search={search}
useRouter={useRouter}
/>
<Selector label="Category" data={tags} useRouter={useRouter} />
<Selector label="Price" data={prices} useRouter={useRouter} />
</div>
);
}
What I tried to add in the search component instead of pushing directly was:
const handleInputChange = (e) => {
setSearchQuery(e.target.value);
updateQueryParams({ search: e.target.value });
};
const updateQueryParams = (newParams) => {
const existingQueryParams = { ...router.query };
const updatedQueryParams = { ...existingQueryParams, ...newParams };
let queryString = router.pathname; // Initialize with router.pathname
const queryKeys = Object.keys(updatedQueryParams);
if (queryKeys.length > 0) {
const queryArray = queryKeys.map((key) => `${key}=${updatedQueryParams[key]}`);
queryString += `?${queryArray.join("&")}`;
}
router.push(queryString);
};```
</details>
# 答案1
**得分**: 0
Your problem is you're just using the last e.target.value for the new search parameter.
Instead of
```javascript
const handleInputChange = (e) => {
setSearchQuery(e.target.value);
push("/?search=" + e.target.value);
};
Try making your searchQuery an array and go with something more like this:
const handleInputChange = (e) => {
setSearchQuery((oldSearch) => [...oldSearch, e.target.value]);
push("/?search=" + searchQuery.join('&'));
};
英文:
Your problem is you're just using the last e.target.value for the new search parameter.
Instead of
const handleInputChange = (e) => {
setSearchQuery(e.target.value);
push("/?search=" + e.target.value);
};
Try making your searchQuery an array and go with something more like this:
const handleInputChange = (e) => {
setSearchQuery((oldSearch) => {[...oldSearch, e.target.value]);
push("/?search=" + searchQuery.join('&');
};
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论