在 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-stringprops.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&parameter2=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-stringnpm 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 参数的主要内容,如果未能解决你的问题,请参考以下文章

如何在 gatsbyjs 中使用参数创建路由

gat和post封装代码和爬虫的5个步奏

GatsbyJS:从 WPGraphQL 查询 Gatsby-image 以获取高级自定义字段

gat和post封装代码

GatsbyJS 从 Restful API 获取数据

如何使用 GatsbyJS 在项目列表中获取数组值?