【发布时间】:2021-10-01 11:33:41
【问题描述】:
我正在创建自己的迷你博客,并正在实现搜索功能。
我使用 Strapi,一个无头 CMS。因此,如果我想搜索特定帖子,我可以在 API 调用中添加 ?_q=search here 以查询这些帖子。
在我的 React 应用程序中,我有一个 Posts 组件,它将页面中的 URL 转发到 API,这可以通过 window.location.pathname + window.location.search 轻松完成。因此,如果有人访问https://exampleblog.com/posts?_q=search here,那么 React 将获取路径名和搜索参数并将其用于对 Strapi 的 API 调用。我这样做是因为它可以节省很多工作。
借助我的搜索功能,我使用来自react-router-dom 的Link 组件作为搜索按钮。有一个状态从文本框中获取值,并更改Link 组件中to 属性的值,使to 看起来像/posts?_q=textbox value。并且由于页面中的路径名和搜索参数被转发到 API,它应该会解析正确的帖子。
我的问题是,如果 URL 中的路径名发生变化(例如 /posts 变为类似 /categories),Link 组件会呈现页面(这是正确的)。 但是,如果只有search 参数发生变化(URL 中的?_q=search here),那么浏览器中的 URL 会发生变化,但不会呈现任何新内容。
我还想补充一点,当从具有不同路径名的页面进行搜索时,搜索 100% 有效,因此搜索参数是有效的。但是,如果我在具有相同路径名的页面上执行搜索,则不会。
根据我的观察,我得出的结论是Link 组件不考虑对 URL 中搜索参数的更改。
下面是一些示例代码。
来自Posts 组件的片段:
const pathname = window.location.pathname + window.location.search;
const {loading, error, data} = useApi(pathname); // Custom hook to resolve API requests. Already knows the hostname.
// Continued code in this component will render the API result
Search 组件的整体:
import React, {useState} from 'react';
import {Link} from 'react-router-dom';
export default function Search() {
const [query, setQuery] = useState('');
return (
<div className="search">
<label>Search</label>
<input type="text" onChange={event => setQuery(event.target.value)}></input>
<Link to={`/posts?_q=${query}`} className="button">
Search
</Link>
</div>
);
}
我的“useApi”自定义钩子:
export default function useApi(endpoint = '/') {
const URI = process.env.URI;
const [state, setState] = useState({
loading: true,
error: false,
data: null
});
useEffect(() => {
(async () => {
try {
const response = await axios.get(URI + endpoint);
const data = response.data;
setState({
loading: false,
error: false,
data
});
} catch (error) {
setState({
loading: false,
error: true,
data: null
});
}
})();
}, [endpoint]);
return state;
}
如您所见,提供给 useApi 钩子的端点参数最终将是window.location.pathname + window.location.search,这意味着它将跟踪必要的更改,包括搜索参数的更改值。
如往常一样,任何帮助将不胜感激。
【问题讨论】:
标签: javascript reactjs hyperlink react-router-dom