在 GatsbyJS 上获取 URL 参数
Posted
技术标签:
【中文标题】在 GatsbyJS 上获取 URL 参数【英文标题】:Getting URL Parameters on GatsbyJS 【发布时间】:2019-05-16 22:20:34 【问题描述】:有没有办法检索在 GatsbyJS 构建的项目页面上传递的 url 参数? 我正在尝试使用 AWS 在我的页面上实现密码重置功能,但他们只能通过发送到用户电子邮件的链接发送参数。
所以流程是这样的:
用户触发忘记密码 -> AWS 通过链接向用户发送电子邮件 -> 链接指向带有参数的我的页面 -> 重置密码表单自动使用传递的参数填充字段
更新
这是我的 App.js 代码:
import Router from "@reach/router"
const App = () => (
<Layout>
<Router>
<Login path="signin" exact component=Login />
<Resources path="api/resources" exact component=Resources />
<Verify path="verify" exact component=Verify />
<Forgot path="forgot" exact component=Forgot />
<Reset path="account/reset/:code" exact component=Reset/>
</Router>
</Layout>
)
export default App;
重置.js:
export default class ResetForm extends Component
constructor(props)
super(props);
this.state =
password: "",
confirmPassword: "",
vercode: "",
email: "",
emailValid: false,
passValid: false,
confirmValid: false,
codeValid: false,
formValid: true,
formErrors :
email: false,
password: false,
confirmPassword: false,
vercode: false,
,
respErrors :
email:
isValid : true,
message : ""
,
password:
isValid : true,
message : ""
,
code :
isValid : true,
message : ""
;
validateField(field, value)
let password = this.state.password
let fieldValidationErrors = this.state.formErrors;
let emailValid = this.state.emailValid
let passValid = this.state.passValid
let confirmValid = this.state.confirmValid
let codeValid = this.state.vercode
let fieldValidationMessages = this.state.respErrors;
switch(field)
case 'email' :
emailValid = validator.isEmail(value);
fieldValidationErrors.email = emailValid ? false : true;
fieldValidationMessages.email.isValid = true;
fieldValidationMessages.email.message = "Invalid E-Mail Address";
break;
case 'password' :
passValid = validator.matches(value, RegExp('^(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*])(?=.8,)'));
fieldValidationMessages.password.message = passValid ? '' : undefined;
if(!validator.matches(value,RegExp('^(?=.*[a-z])(?=.*[A-Z])')))
fieldValidationMessages.password.message = "At least 1 Upper case character is required";
if(!validator.matches(value,RegExp('^(?=.*[!@#$%^&*])')))
fieldValidationMessages.password.message = "At least 1 Symbol is required";
if(!validator.matches(value,RegExp('^(?=.8,)')))
fieldValidationMessages.password.message = "Password must have at least 8 characters";
fieldValidationErrors.password = passValid ? false : true;
break;
case 'confirmPassword' :
confirmValid = validator.equals(value, password);
fieldValidationErrors.confirmPassword = confirmValid ? false : true;
break;
case 'vercode' :
codeValid = !validator.isEmpty(value);
fieldValidationErrors.vercode = codeValid ? false : true;
break;
default :
break
this.setState(
formErrors: fieldValidationErrors,
emailValid: emailValid,
passValid: passValid,
confirmValid: confirmValid,
codeValid: codeValid,
, this.validateForm())
validateForm()
this.setState(
formValid:
this.state.emailValid && this.state.confirmValid && this.state.codeValid && this.state.passValid
)
handleChange = event =>
const name = event.target.id;
const value = event.target.value;
this.setState(
[name]: value
,
() =>
this.validateField(name, value)
);
handleSubmit = async (event) =>
event.preventDefault()
const state = this.state
await handleReset(state)
.then(async (data) =>
if(data.isValid)
await handleLogin(state)
.then(() =>
navigate('/')
)
.catch(err => console.log(err))
else
switch (data.code)
case CODE_RESET.RESET_EXPIRED:
data.message = "The verification code you have submitted is already expired."
break
case CODE_RESET.RESET_MISMATCH:
data.message = "The verification code you have submitted is invalid."
break
default:
data.message = "Something went wrong."
break;
this.setState(
[state.respErrors.code.isValid] : data.isValid,
[state.respErrors.code.message] : data.message
)
)
.catch(async(err) =>
console.log(err)
)
render()
if(isLoggedIn())
navigate(`/`)
return (
<Row className=[formStyles.formContainer, "row"].join(' ') >
<Col sm=
size:12
md=
size: 8,
offset: 2
>
<Form
onSubmit=this.handleSubmit
>
<h3 style=
fontWeight: 'bolder'
>
Reset Password
</h3>
<FormGroup>
<Label for="email">Email</Label>
<Input
id="email"
autoFocus
type="email"
name="email"
value=this.state.email.value
onChange=this.handleChange
className=formStyles.signUp
valid=this.state.emailValid
invalid=(this.state.formErrors.email || !this.state.respErrors.email.isValid ) ? true : undefined
/>
<FormFeedback invalid=this.state.respErrors.email.isValid ? '' : undefined>
this.state.respErrors.email.message
</FormFeedback>
</FormGroup>
<FormGroup>
<Label for="password">New Password</Label>
<Input
id="password"
type="password"
name="password"
value=this.state.password.value
onChange=this.handleChange
className=formStyles.signUp
valid=this.state.passValid
invalid=this.state.formErrors.password ? true : undefined
/>
<FormText invalid=this.state.respErrors.password.isValid ? '' : undefined>
this.state.respErrors.password.message
</FormText>
</FormGroup>
<FormGroup>
<Label for="confirmPassword">Confirm Password</Label>
<Input
id="confirmPassword"
type="password"
name="confirmPassword"
value=this.state.confirmPassword.value
onChange=this.handleChange
className=formStyles.signUp
valid=this.state.confirmValid
invalid=this.state.formErrors.confirmPassword ? true : undefined
/>
<FormFeedback
invalid=this.state.formErrors.confirmPassword ? '' : undefined
>
Password does not match
</FormFeedback>
</FormGroup>
<FormGroup>
<Label for="vercode">Verification Code</Label>
<Input
id="vercode"
type="text"
name="vercode"
maxLength=6
value=this.state.vercode.value
onChange=this.handleChange
className=formStyles.signUp
valid=this.state.codeValid.value
invalid=this.state.formErrors.vercode || !this.state.respErrors.code.isValid ? true : undefined
/>
<FormFeedback invalid=this.state.respErrors.code.isValid ? '' : undefined >
this.state.respErrors.code.message
</FormFeedback>
</FormGroup>
<Button
color="primary"
disabled=!this.state.formValid
>
Submit
</Button>
</Form>
</Col>
</Row>
)
【问题讨论】:
默认情况下,我相信 gatsby 使用到达路由器,但如果您没有对其进行一些自定义,它的配置方式并没有太多可玩的地方。以下是到达路由器的文档:reach.tech/router 你能通过查询location
得到你需要的东西吗?
我尝试使用它和 console.log(this.props),但它返回为空。
对于@reach/router,我正在使用它并将它放在我的App.js中,所以当用户导航到我的页面时,我让它导入页面容器并且还需要传递查询详细信息
如果你能分享一些你的代码会更有帮助。
我已经用我拥有的 App.js 代码更新了原始帖子@JoshuaTerrill
【参考方案1】:
使用props.location
,引入in Gatsby v2。它由@reach/router 通过props
提供给所有组件。
function Component(props)
// use props.location...
return ...
【讨论】:
我可以使用另一个插件query-string
和 props.location
来解决这个问题。感谢您的建议!【参考方案2】:
如MDN 所述使用URLSearchParams.get()
:
// Get the location object that is implicitly passed as props
// for every page in the `pages` folder
const Index = ( location ) =>
console.log(location); // inspect location for yourself
// the parameter to return for URL. Example:
// https://localhost:8000/?parameter1=firstParam¶meter2=secondParam
const params = new URLSearchParams(location.search);
const parameter1 = params.get("parameter1");
const parameter2 = params.get("parameter2");
console.log(parameter1); // -> "firstParam"
console.log(parameter2); // -> "secondParam"
// ...
替代方案:包query-string
yarn add query-string
或 npm i --save query-string
import * as queryString from "query-string";
// Get the location object that is implicitly passed as props
// for every page in the `pages` folder
const Index = ( location ) =>
console.log(location); // inspect location for yourself
// query-string parses the parameters that are contained in the location object
const parameter1, parameter2 = queryString.parse(location.search);
console.log(parameter1);
console.log(parameter2);
// ...
【讨论】:
以上是关于在 GatsbyJS 上获取 URL 参数的主要内容,如果未能解决你的问题,请参考以下文章