Graphql 初体验 第十一章 | #13 Hitting the API(实现了登录注册表单)

对应内容:#13 Hitting the API | Build a Complete App with GraphQL, Node.js, MongoDB and React.js

主要内容:

  • 完成登录、注册表单,及其对应的逻辑
  • 由于涉及前后端的通信,在后端实现跨域的中间件【及其重要】

1 完成表单部分的页面及其对应逻辑,修复了前面的BUG

这里ES6中的类,很多人不是很熟悉,类的属性的实现方式分两种,一种是写在constructor中的属性,一种是类字段,定义在构造函数之外的,类字段是直接赋值在类的对象实例上的,而普通属性是写在类的原型上的,因此类字段声明的函数表达式,是不需要进行this绑定的,在react官方文档中,明确说明了class 中声明的函数,要在构造函数中绑定一下this,这里要注意!!!!

这里用的是ref进行绑定,而没有使用官方文档中的setState,第二种写起来比较麻烦。

import React, { Component } from 'react';
import './Auth.css';


class AuthPage extends Component  {
    constructor (props) {
        super(props);
        this.emailEl = React.createRef();
        this.passwordEl = React.createRef();

        this.state = {
            isLoginMode: true
        }
    }

    submitHandler = async (event) => {
        event.preventDefault();
        let email = this.emailEl.current.value;
        let password = this.passwordEl.current.value;
        if (email.trim() === "" || password.trim() === "") {
            return false;
        }
        const requestBody = {
            query: `
            mutation {
                createUser(userInput: {email: "${email}", password: "${password}"}) {
                    _id
                    email
                }
            }
            `
        };

        if (this.state.isLoginMode) {
            requestBody.query = `
                query {
                    login(email: "${email}", password: "${password}") {
                        _id
                        token
                        tokenExpiration
                    }
                }
                `;
        }
        let response, data;
        try {
            response = await fetch(`http://localhost:3030/graphql`, {
                method: "POST",
                headers: {
                    "Content-Type": "application/json"
                },
                body: JSON.stringify(requestBody)
            });

            data = await response.json();
        } catch (error) {
            throw error;
        }
    }

    swithHandler = () => {
        this.setState(prevState => {
            return {
                isLoginMode: !prevState.isLoginMode
            };
        })
    }
    

    render () {
        return (
            <React.Fragment>
                <h1>The Auth Page</h1>
                <form action="" className="auth-form" onSubmit={ this.submitHandler }>
                    <div className="form-control">
                        <label htmlFor="email">Email</label>
                        <input type="email" id="email" ref={this.emailEl} />
                    </div>
                    <div className="form-control">
                        <label htmlFor="password">Password</label>
                        <input type="password" id="password" ref={this.passwordEl} />
                    </div>
                    <div className="form-action">
                        <button type="submit">Submit</button>
                        <button type="button" onClick={this.swithHandler}>
                            swith to {this.state.isLoginMode ? "Signup" : "Signin"}
                        </button>
                    </div>
                </form>
            </React.Fragment>
        );
    }
}

export default AuthPage;

Auth.css

.auth-form {
    width: 300px;
    margin: 1rem auto;
}
label, input {
    display: block;
    width: 100%;
}
.form-action button {
    font: inherit;
}

在后端的auth resolver中我之前的代码有一个bug,在这里进行修复:
在这里插入图片描述
第四行那里少了一个await,并且稍微修改了一些逻辑

2 后端实现跨域中间件

app.use((req, res, next) => {
    res.setHeader("Access-Control-Allow-Origin", "*");
    res.setHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS");
    res.setHeader("Access-Control-Allow-Headers", "Content-Type,Authorization");
    if (req.method === "OPTIONS") {
        return res.sendStatus(200);
    }
    next();
})

具体原因,一行两行说不清楚,请在mdn中搜索cors或跨越。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值