React中如何获取URL参数的值
How to get the value from URL params in React
具有以下组件:
import { ChangeEvent, useCallback, useState } from 'react';
export function SearchComponent() {
const [searchValue, setSearchValue] = useState<string>('');
const updateSearchValue = useCallback((event: ChangeEvent<HTMLInputElement>) => {
setSearchValue(event.target.value);
}, []);
return (
<div>
<input value={searchValue} onChange={updateSearchValue} />
</div>
);
}
它用输入中引入的值更新状态值,searchValue
。
使用该值,URL 更新如下:
window.location.hash = searchValue ? `?searchBy=${searchValue}` : '';
在URL的基础上多加了一个#
,之前是example.com/test
,现在是example.com/test#?searchBy=my_input
,不过问题不大。
我想要的是能够直接修改输入并将新值存储在组件中,所以我试过这样:
const queryParams = new URLSearchParams(window.location.search);
const searchBy = queryParams.get('searchBy');
记录时,queryParams
是一个空对象,而 searchBy
是 null
。
如果用户要编辑该值,是否有办法存储 URL 中的值?
问题
问题是 window.location.hash = searchValue ? `?searchBy=${searchValue}` : '';
更新了位置哈希,从而将 "#"
添加到 URL,而 没有 [=38] =]window.location.search
,也就是URL.
的queryString部分
使用 window.location
也有点像 anti-pattern,因为它会改变位置并强制重新加载页面。最好使用 react-router-dom
提供的工具来发出导航操作,而不是重新加载整个应用程序。
建议的解决方案
使用 react-router-dom@5
您将需要使用 useHistory and useLocation hooks and access the location.search
value and instantiate your own URLSearchParams 对象。从 queryString 设置初始 searchValue
状态,并使用 useEffect
挂钩更新搜索参数,并使用更新的 queryString 发出到当前路由的命令式重定向。
示例:
import { useLocation, useHistory } from 'react-router-dom';
export function SearchComponent() {
const history = useHistory();
const { pathname, search } = useLocation();
const searchParams = React.useMemo(() => new URLSearchParams(search), [
search
]);
const [searchValue, setSearchValue] = useState<string>(
searchParams.get("searchBy") || ""
);
useEffect(() => {
searchParams.set("searchBy", searchValue);
history.replace({
pathname,
search: searchParams.toString(),
});
}, [history, pathname, searchParams, searchValue]);
const updateSearchValue = useCallback((event: ChangeEvent<HTMLInputElement>) => {
setSearchValue(event.target.value);
}, []);
return (
<div>
<input value={searchValue} onChange={updateSearchValue} />
</div>
);
}
具有以下组件:
import { ChangeEvent, useCallback, useState } from 'react';
export function SearchComponent() {
const [searchValue, setSearchValue] = useState<string>('');
const updateSearchValue = useCallback((event: ChangeEvent<HTMLInputElement>) => {
setSearchValue(event.target.value);
}, []);
return (
<div>
<input value={searchValue} onChange={updateSearchValue} />
</div>
);
}
它用输入中引入的值更新状态值,searchValue
。
使用该值,URL 更新如下:
window.location.hash = searchValue ? `?searchBy=${searchValue}` : '';
在URL的基础上多加了一个#
,之前是example.com/test
,现在是example.com/test#?searchBy=my_input
,不过问题不大。
我想要的是能够直接修改输入并将新值存储在组件中,所以我试过这样:
const queryParams = new URLSearchParams(window.location.search);
const searchBy = queryParams.get('searchBy');
记录时,queryParams
是一个空对象,而 searchBy
是 null
。
如果用户要编辑该值,是否有办法存储 URL 中的值?
问题
问题是 window.location.hash = searchValue ? `?searchBy=${searchValue}` : '';
更新了位置哈希,从而将 "#"
添加到 URL,而 没有 [=38] =]window.location.search
,也就是URL.
使用 window.location
也有点像 anti-pattern,因为它会改变位置并强制重新加载页面。最好使用 react-router-dom
提供的工具来发出导航操作,而不是重新加载整个应用程序。
建议的解决方案
使用 react-router-dom@5
您将需要使用 useHistory and useLocation hooks and access the location.search
value and instantiate your own URLSearchParams 对象。从 queryString 设置初始 searchValue
状态,并使用 useEffect
挂钩更新搜索参数,并使用更新的 queryString 发出到当前路由的命令式重定向。
示例:
import { useLocation, useHistory } from 'react-router-dom';
export function SearchComponent() {
const history = useHistory();
const { pathname, search } = useLocation();
const searchParams = React.useMemo(() => new URLSearchParams(search), [
search
]);
const [searchValue, setSearchValue] = useState<string>(
searchParams.get("searchBy") || ""
);
useEffect(() => {
searchParams.set("searchBy", searchValue);
history.replace({
pathname,
search: searchParams.toString(),
});
}, [history, pathname, searchParams, searchValue]);
const updateSearchValue = useCallback((event: ChangeEvent<HTMLInputElement>) => {
setSearchValue(event.target.value);
}, []);
return (
<div>
<input value={searchValue} onChange={updateSearchValue} />
</div>
);
}