如何在我的 routes.jsx 文件中定义路由,以便在从 Twitter 的服务器重定向后从 Twitter 的单点登录过程生成的 URL 中捕获 __firebase_request_key
参数值?
http://localhost:8000/#/signin?_k=v9ifuf&__firebase_request_key=blablabla
我尝试使用以下路由配置,但 :redirectParam
没有捕捉到提到的参数:
<Router>
<Route path="/" component={Main}>
<Route path="signin" component={SignIn}>
<Route path=":redirectParam" component={TwitterSsoButton} />
</Route>
</Route>
</Router>
query strings
"?var1=val&var2=val2" , url paramters
: "/photos/:companyiD/new"
React Router v6,使用钩子
在 react-router-dom v6 中有一个名为 useSearchParams 的新钩子。所以随着
const [searchParams, setSearchParams] = useSearchParams();
searchParams.get("__firebase_request_key")
你会得到"blablabla"
。请注意,searchParams 是 URLSearchParams 的一个实例,它还实现了一个迭代器,例如用于使用 Object.fromEntries 等。
React Router v4/v5,没有钩子,通用
React Router v4 不再为您解析查询,但您只能通过 this.props.location.search
(或 useLocation,见下文)访问它。原因参见nbeuchat's answer。
例如,将 qs 库导入为 qs
,您可以这样做
qs.parse(this.props.location.search, { ignoreQueryPrefix: true }).__firebase_request_key
另一个库是 query-string。有关解析搜索字符串的更多想法,请参阅 this answer。如果您不需要IE-compatibility,您也可以使用
new URLSearchParams(this.props.location.search).get("__firebase_request_key")
对于功能组件,您可以将 this.props.location
替换为钩子 useLocation。请注意,您可以使用 window.location.search
,但这不允许在更改时触发 React 渲染。如果您的(非功能性)组件不是 Switch
的直接子组件,您需要使用 withRouter 来访问路由器提供的任何道具。
反应路由器 v3
React Router 已经为您解析了位置并将其作为道具传递给您的 RouteComponent。您可以通过以下方式访问查询(在 URL 中的 ? 之后)部分
this.props.location.query.__firebase_request_key
如果您正在查找路径参数值,在路由器内部用冒号 (:) 分隔,可以通过以下方式访问这些值
this.props.match.params.redirectParam
这适用于 React Router v3 的后期版本(不确定是哪个版本)。据报道,较旧的路由器版本使用 this.props.params.redirectParam
。
一般的
nizam.sp 的建议
console.log(this.props)
在任何情况下都会有所帮助。
反应路由器 v4
使用 component
<Route path="/users/:id" component={UserPage}/>
this.props.match.params.id
组件会使用 route 道具自动呈现。
使用 render
<Route path="/users/:id" render={(props) => <UserPage {...props} />}/>
this.props.match.params.id
路由道具被传递给渲染函数。
query params
时遇到了类似问题。如果您正在寻找 query params
,则 React Router 4 中的 this.props.location.query 已被删除(当前使用 v4.1.1)。看到这个答案:stackoverflow.com/a/43630848/1508105
/users/?q=...
,但您可以有 /user?q=...
。您应该在 React Router v4 中使用 this.props.location.search
并自己解析结果,如下面的回答中所述。
this.props.location.search
不存在。
反应路由器 v3
使用 React Router v3,您可以从 this.props.location.search
(?qs1=naisarg&qs2=parmar) 获取查询字符串。例如,使用 let params = queryString.parse(this.props.location.search)
,将给出 { qs1 : 'naisarg', qs2 : 'parmar'}
反应路由器 v4
使用 React Router v4,this.props.location.query
不再存在。您需要改用 this.props.location.search
并自行解析查询参数或使用现有包(例如 query-string
)解析查询参数。
例子
这是一个使用 React Router v4 和 query-string
库的最小示例。
import { withRouter } from 'react-router-dom';
import queryString from 'query-string';
class ActivateAccount extends Component{
someFunction(){
let params = queryString.parse(this.props.location.search)
...
}
...
}
export default withRouter(ActivateAccount);
合理的
React Router 团队移除 query
属性的理由是:
有许多流行的包在查询字符串解析/字符串化方面略有不同,这些差异中的每一个对于某些用户来说可能是“正确”的方式,而对于其他用户来说可能是“不正确的”方式。如果 React Router 选择了“正确”的那个,那它只适合某些人。然后,它需要为其他用户添加一种方法来替代他们喜欢的查询解析包。 React Router 对搜索字符串的内部使用没有要求它解析键值对,因此它不需要选择其中哪一个应该是“正确的”。 [...] 4.0 采用的方法是去掉所有“包含电池”的特性,回到基本路由。如果您需要查询字符串解析或异步加载或 Redux 集成或其他非常具体的东西,那么您可以将其添加到专门针对您的用例的库中。你不需要的东西更少,你可以根据你的特定偏好和需求定制东西。
您可以在 GitHub 上找到完整的讨论。
据我所知,您可以通过三种方法做到这一点。
1.使用正则表达式获取查询字符串。
2.可以使用浏览器api。图片当前网址是这样的:
http://www.google.com.au?token=123
我们只想得到 123;
第一的
const query = new URLSearchParams(this.props.location.search);
然后
const token = query.get('token')
console.log(token)//123
3. 使用名为“查询字符串”的第三个库。首先安装它
npm i query-string
然后将其导入到当前的 javascript 文件中:
import queryString from 'query-string'
下一步是在当前 url 中获取 'token',执行以下操作:
const value=queryString.parse(this.props.location.search);
const token=value.token;
console.log('token',token)//123
希望能帮助到你。
更新于 25/02/2019
如果当前 url 如下所示:
http://www.google.com.au?app=home&act=article&aid=160990
我们定义一个函数来获取参数:
function getQueryVariable(variable)
{
var query = window.location.search.substring(1);
console.log(query)//"app=article&act=news_content&aid=160990"
var vars = query.split("&");
console.log(vars) //[ 'app=article', 'act=news_content', 'aid=160990' ]
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
console.log(pair)//[ 'app', 'article' ][ 'act', 'news_content' ][ 'aid', '160990' ]
if(pair[0] == variable){return pair[1];}
}
return(false);
}
我们可以通过以下方式获得“援助”:
getQueryVariable('aid') //160990
React Router v4 不再具有 props.location.query
对象(参见github讨论)。因此,接受的答案不适用于较新的项目。
v4 的解决方案是使用外部库 query-string 来解析 props.location.search
const qs = require('query-string');
//or
import * as qs from 'query-string';
console.log(location.search);
//=> '?foo=bar'
const parsed = qs.parse(location.search);
console.log(parsed);
//=> {foo: 'bar'}
{'?foo': 'bar'}
var prefixed = qs.parse('?a=b&c=d', { ignoreQueryPrefix: true });
应该修复它。在此处找到示例:github.com/ljharb/qs
const parsed = qs.parse(location.search.replace('?', ''));
使用 React 挂钩时,无法访问 this.props.location
。要捕获 url 参数,请使用 window
对象。
const search = window.location.search;
const params = new URLSearchParams(search);
const foo = params.get('bar');
反应路由器 5.1+
5.1 引入了各种钩子,例如 useLocation
和 useParams
,可以在这里使用。
例子:
<Route path="/test/:slug" component={Dashboard} />
然后如果我们访问说
http://localhost:3000/test/signin?_k=v9ifuf&__firebase_request_key=blablabla
你可以像这样检索它
import { useLocation } from 'react-router';
import queryString from 'query-string';
const Dashboard: React.FC = React.memo((props) => {
const location = useLocation();
console.log(queryString.parse(location.search));
// {__firebase_request_key: "blablabla", _k: "v9ifuf"}
...
return <p>Example</p>;
}
useParams
与此问题更相关
有了这个单行,你可以在 React Hook 和 React 类组件中的任何地方使用纯 JavaScript。
https://www.hunterisgod.com/?city=Leipzig
let city = (new URLSearchParams(window.location.search)).get("city")
反应路由器 v4
const urlParams = new URLSearchParams(this.props.location.search)
const key = urlParams.get('__firebase_request_key')
请注意,它目前是实验性的。
在此处检查浏览器兼容性:https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/URLSearchParams#Browser_compatibility
http://localhost:8000/#/signin?id=12345
import React from "react";
import { useLocation } from "react-router-dom";
const MyComponent = () => {
const search = useLocation().search;
const id=new URLSearchParams(search).get("id");
console.log(id);//12345
}
您可以检查react-router,简单地说,您可以使用代码获取查询参数,只要您在路由器中定义:
this.props.params.userId
props.params
用于 URL 参数(在反应路由器中以 ':' 为前缀的 url 段),props.location.query
存储查询字符串参数(在 '?' 之后)并且是 OP 想要的。
如果你的路由器是这样的
<Route exact path="/category/:id" component={ProductList}/>
你会得到这样的id
this.props.match.params.id
不是反应方式,但我相信这个单行功能可以帮助你:)
const getQueryParams = (query = null) => (query||window.location.search.replace('?','')).split('&').map(e=>e.split('=').map(decodeURIComponent)).reduce((r,[k,v])=>(r[k]=v,r),{});
示例:
URL: ...?a=1&b=c&d=test
代码:
getQueryParams()
//=> {a: "1", b: "c", d: "test"}
getQueryParams('type=user&name=Jack&age=22')
//=> {type: "user", name: "Jack", age: "22" }
说有一个url如下
http://localhost:3000/callback?code=6c3c9b39-de2f-3bf4-a542-3e77a64d3341
如果我们想从该 URL 中提取代码,下面的方法将起作用。
const authResult = new URLSearchParams(window.location.search);
const code = authResult.get('code')
无需 3rd 方库或复杂的解决方案即可完成所有操作。这是如何
let myVariable = new URLSearchParams(history.location.search).get('business');
您唯一需要更改的是带有您自己的参数名称的“业务”一词。
例如 url.com?business=hello
myVariable 的结果将是 hello
history.location.search
在我的情况下不起作用,而不是我使用 window.location.search
并且它可以完美地工作。 new URLSearchParams(window.location.search).get('bussiness')
反应路由器 Dom V6 https://reactrouter.com/docs/en/v6/hooks/use-search-params
import * as React from "react";
import { useSearchParams } from "react-router-dom";
function App() {
let [searchParams, setSearchParams] = useSearchParams();
function handleSubmit(event) {
event.preventDefault();
// The serialize function here would be responsible for
// creating an object of { key: value } pairs from the
// fields in the form that make up the query.
let params = serializeFormQuery(event.target);
setSearchParams(params);
}
return (
<div>
<form onSubmit={handleSubmit}>{/* ... */}</form>
</div>
);
}
直到 React 路由器 Dom V5
function useQueryParams() {
const params = new URLSearchParams(
window ? window.location.search : {}
);
return new Proxy(params, {
get(target, prop) {
return target.get(prop)
},
});
}
React 钩子很棒
如果您的网址看起来像 /users?page=2&count=10&fields=name,email,phone
// app.domain.com/users?page=2&count=10&fields=name,email,phone
const { page, fields, count, ...unknown } = useQueryParams();
console.log({ page, fields, count })
console.log({ unknown })
如果您的查询参数包含连字符(“-”)或空格(“”),那么您不能像 { page, fields, count, ...unknown }
您需要执行传统的任务,例如
// app.domain.com/users?utm-source=stackOverFlow
const params = useQueryParams();
console.log(params['utm-source']);
如果您没有得到 this.props
... 根据其他答案所期望的,您可能需要使用 withRouter
(docs v4):
import React from 'react'
import PropTypes from 'prop-types'
import { withRouter } from 'react-router'
// A simple component that shows the pathname of the current location
class ShowTheLocation extends React.Component {
static propTypes = {
match: PropTypes.object.isRequired,
location: PropTypes.object.isRequired,
history: PropTypes.object.isRequired
}
render() {
const { match, location, history } = this.props
return (
<div>You are now at {location.pathname}</div>
)
}
}
// Create a new component that is "connected" (to borrow redux terminology) to the router.
const TwitterSsoButton = withRouter(ShowTheLocation)
// This gets around shouldComponentUpdate
withRouter(connect(...)(MyComponent))
// This does not
connect(...)(withRouter(MyComponent))
我很难解决这个问题。如果上述方法都不起作用,您可以试试这个。我正在使用 create-react-app
要求
react-router-dom": "^4.3.1"
解决方案
在指定路由器的位置
<Route path="some/path" ..../>
像这样添加您要传入的参数名称
<Route path="some/path/:id" .../>
在您渲染一些/路径的页面上,您可以指定它以查看参数名称调用ID,如下所示
componentDidMount(){
console.log(this.props);
console.log(this.props.match.params.id);
}
在您导出默认值的最后
export default withRouter(Component);
记得包含导入
import { withRouter } from 'react-router-dom'
当 console.log(this.props) 你将能够传递什么。玩得开心!
RouteComponentProps<{id: number}>
React Router v5.1 引入了 hooks:
为了
<Route path="/posts/:id">
<BlogPost />
</Route>
您可以使用 hook 访问 params / id:
const { id } = useParams();
更多here。
withRouter
HOC 中,例如在导出行中:export default withRouter(Component);
它允许您访问名为 match
、location
和 history
的属性。有关详细信息,请查看此处:v5.reactrouter.com/web/api/withRouter
实际上没有必要使用 3rd 方库。我们可以用纯 JavaScript 制作。
考虑以下 URL:
https://example.com?yourParamName=yourParamValue
现在我们得到:
const url = new URL(window.location.href);
const yourParamName = url.searchParams.get('yourParamName');
简而言之
const yourParamName = new URL(window.location.href).searchParams.get('yourParamName')
另一种智能解决方案(推荐)
const params = new URLSearchParams(window.location.search);
const yourParamName = params.get('yourParamName');
简而言之
const yourParamName = new URLSearchParams(window.location.search).get('yourParamName')
笔记:
对具有多个值的参数使用“getAll”而不是“get”
https://example.com?yourParamName[]=yourParamValue1&yourParamName[]=yourParamValue2
const yourParamName = new URLSearchParams(window.location.search).getAll('yourParamName[]')
结果将如下所示:
["yourParamValue1", "yourParamValue2"]
尝试这个
http://localhost:4000/#/amoos?id=101
// ReactJS
import React from "react";
import { useLocation } from "react-router-dom";
const MyComponent = () => {
const search = useLocation().search;
const id = new URLSearchParams(search).get("id");
console.log(id); //101
}
// VanillaJS
const id = window.location.search.split("=")[1];
console.log(id); //101
从 v4 开始的 React router
不再直接在其 location
对象中为您提供 query params
。原因是
有许多流行的包在查询字符串解析/字符串化方面略有不同,这些差异中的每一个对于某些用户来说可能是“正确”的方式,而对于其他用户来说可能是“不正确的”方式。如果 React Router 选择了“正确”的那个,那它只适合某些人。然后,它需要为其他用户添加一种方法来替代他们喜欢的查询解析包。 React Router 对搜索字符串的内部使用没有要求它解析键值对,因此它不需要选择其中哪一个应该是“正确的”。
包括了这一点后,只在需要查询对象的视图组件中解析 location.search 会更有意义。
您可以通过覆盖 react-router
中的 withRouter
来一般地执行此操作,例如
customWithRouter.js
import { compose, withPropsOnChange } from 'recompose';
import { withRouter } from 'react-router';
import queryString from 'query-string';
const propsWithQuery = withPropsOnChange(
['location', 'match'],
({ location, match }) => {
return {
location: {
...location,
query: queryString.parse(location.search)
},
match
};
}
);
export default compose(withRouter, propsWithQuery)
this.props.params.your_param_name
将起作用。
这是从查询字符串中获取参数的方法。
请执行 console.log(this.props);
以探索所有可能性。
componentDidMount(){
//http://localhost:3000/service/anas
//<Route path="/service/:serviceName" component={Service} />
const {params} =this.props.match;
this.setState({
title: params.serviceName ,
content: data.Content
})
}
也许有点晚了,但这个反应钩子可以帮助你在 URL 查询中获取/设置值:https://github.com/rudyhuynh/use-url-search-params(由我编写)。
它在有或没有 react-router
的情况下都有效。以下是您的案例中的代码示例:
import React from "react";
import { useUrlSearchParams } from "use-url-search-params";
const MyComponent = () => {
const [params, setParams] = useUrlSearchParams()
return (
<div>
__firebase_request_key: {params.__firebase_request_key}
</div>
)
}
您可以使用以下反应挂钩:
如果 url 更改 SSR,则挂钩状态更新:typeof window === "undefined",只是检查 window 会导致错误(试一试)代理对象隐藏实现,因此返回 undefined 而不是 null
所以这是将搜索参数作为对象的函数:
const getSearchParams = <T extends object>(): Partial<T> => {
// server side rendering
if (typeof window === "undefined") {
return {}
}
const params = new URLSearchParams(window.location.search)
return new Proxy(params, {
get(target, prop, receiver) {
return target.get(prop as string) || undefined
},
}) as T
}
然后像这样使用它作为钩子:
const useSearchParams = <T extends object = any>(): Partial<T> => {
const [searchParams, setSearchParams] = useState(getSearchParams())
useEffect(() => {
setSearchParams(getSearchParams())
}, [typeof window === "undefined" ? "once" : window.location.search])
return searchParams
}
如果您的网址如下所示:
/app?page=2&count=10
你可以这样读:
const { page, count } = useQueryParams();
console.log(page, count)
count
而不是 fields
?或者 fields
是从哪里来的?
useQueryParams
甚至不存在。我提出了另一个没有被接受的解决方案 for this answer,然后这个答案是在那之后写的。该答案和这个答案的编辑历史应该可以为您提供全貌。抱歉,我没有时间处理这个问题。希望能帮助到你。
反应路由器 v6
来源:Getting Query Strings (Search Params) in React Router
使用新的 useSearchParams
挂钩和 .get()
方法:
const Users = () => {
const [searchParams] = useSearchParams();
console.log(searchParams.get('sort')); // 'name'
return <div>Users</div>;
};
使用这种方法,您可以读取一个或几个参数。
BONUS 获取参数作为对象:
如果您需要一次获取所有查询字符串参数,那么我们可以像这样使用 Object.fromEntries
:
const Users = () => {
const [searchParams] = useSearchParams();
console.log(Object.fromEntries([...searchParams])); // ▶ { sort: 'name', order: 'asecnding' }
return <div>Users</div>;
};
阅读more并现场演示:Getting Query Strings (Search Params) in React Router
您可以创建简单的钩子来从当前位置提取搜索参数:
import React from 'react';
import { useLocation } from 'react-router-dom';
export function useSearchParams<ParamNames extends string[]>(...parameterNames: ParamNames): Record<ParamNames[number], string | null> {
const { search } = useLocation();
return React.useMemo(() => { // recalculate only when 'search' or arguments changed
const searchParams = new URLSearchParams(search);
return parameterNames.reduce((accumulator, parameterName: ParamNames[number]) => {
accumulator[ parameterName ] = searchParams.get(parameterName);
return accumulator;
}, {} as Record<ParamNames[number], string | null>);
}, [ search, parameterNames.join(',') ]); // join for sake of reducing array of strings to simple, comparable string
}
然后你可以像这样在你的功能组件中使用它:
// current url: http://localhost:8000/#/signin?_k=v9ifuf&__firebase_request_key=blablabla
const { __firebase_request_key } = useSearchParams('__firebase_request_key');
// current url: http://localhost:3000/home?b=value
const searchParams = useSearchParameters('a', 'b'); // {a: null, b: 'value'}
也许有人可以帮助澄清原因,但如果你试图从 App.js 页面上全新安装的 Create React App 中点击道具来查找位置,你会得到:
TypeError:无法读取未定义的属性“搜索”
即使我有 App.js 作为主路由:
<Route exact path='/' render={props => (
仅在 App.js 上,使用 window.location 对我有用:
import queryString from 'query-string';
...
const queryStringParams = queryString.parse(window.location.search);
在需要访问参数的组件中可以使用
this.props.location.state.from.search
这将显示整个查询字符串(?
符号之后的所有内容)
不定期副业成功案例分享
console.dir()
...至少 :)react-router-dom
中,我必须使用withRouter
才能完成这项工作!