登录界面的核心是表单控制, 包括自定义所有的表单内容为组件, 阻止默认事件发生, 自定义表单提交的事件等等.

这里还有一个登录状态管理的问题, 留到后边再说

  1. 登录页
  2. input组件
  3. 按钮组件

登录页

登录页也是老套路了, 先做一个页面, 然后是两个组件用来显示表单.

在其中, 把每个登录框和按钮, 也做成一个自定义组件可以复用.

依然创建组件然后导入:

import React from "react";

import './sign-in-and-sign-up.styles.scss';

const SingInAndSignUpPage = () => (
    <div className='sign-in-and-sign-up'>SIGN IN</div>
);

export default SingInAndSignUpPage;

app.js中导入然后设置路由是/signin, 这都是常规操作, 不说了.

接下来是在页面里设置组件, 第一个组件就是SIGN-IN这个表单组件:

import React from "react";

import './sign-in.styles.scss';

class SignIn extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            email: '',
            password: ''
        }
    }

    handleSubmit = event =>{
        event.preventDefault();

        this.setState({email:'', password: ''})
    }

    handleChange = event =>{
        const {value, name} = event.target;
        this.setState({
            [name]: value
        })
    }


    render() {
        return (
            <div className='sign-in'>
                <h2>I already have a account</h2>
                <span>Sign in with your email and password</span>
                <form onSubmit={this.handleSubmit}>
                    <input type="text" name='email' value = {this.state.email} onChange={this.handleChange} required/>
                    <label>Email</label>
                    <input type="password" name='password' value = {this.state.password} onChange={this.handleChange} required/>
                    <label>Password</label>

                    <input type="submit" value='Submit'/>
                </form>
            </div>
        );
    }
}

export default SignIn;

这里有两个函数,绑定在了表单提交和两个框的变化事件上, 用于将当前的state设置为输入的内容, 很显然, 之后在点击发送的时候就可以根据state的内容来发送.

input组件

接下来任务是编写一个通用的input组件, 然后只要给其传入各种参数, 就可以控制其成为普通的, email, 密码等各种格式, 一次编写好多次使用.

创建组件目录form-input和内部的文件,

import React from "react";

import './form-input.styles.scss';

const FormInput = ({handleChange, label, ...otherProps}) =>{
    return (
        <div className='group'>
            <input className='form-input' onChange={handleChange} {...otherProps} />
            {
                label ?
                    (<label className={`${otherProps.value.length ? 'shrink' : ""} form-input-label`}>{label}</label>) : null
            }
        </div>
    );
}

export default FormInput;

这里的关键是利用样式来作出这个效果, 还有就是根据传入的label不同, 来是否显示label. 只要不传, 就不会渲染那个浮动的label标签.

这里的样式很有意思, 将label标签固定在input框内部, 为焦点或者有输入内容的时候, 就让其浮动和变小到上边去. 学到了.

按钮组件

按钮组件需要搭配Input组件一起使用, 其关键的任务就是被按下之后, 需要将表单的内容进行提交, 由于表单组件已经设置了提交的事件, 因此就是将这个事件传递给按钮组件即可:

而且按键组件也要做成一个无状态的组件, 类似于input组件, 这样可以在各处复用.

import React from "react";

import './custom-button.styles.scss';

const CustomButton = ({children, ...otherProps}) => (
    <button className='custom-button' {...otherProps}>
        {children}
    </button>
);

export default CustomButton;

很显然, 需要从父组件把内容传递过来, 这里不需要传递提交事件, 只需要把button设置为submit, 点击之后触发是的表单的事件, 而表单的事件是通过特殊的属性onSubmit来设置的, 所以这个button组件可以方便的在所有表单中使用.:

import CustomButton from "../custom-button/custom-button.component";

render() {
    return (
        <div className='sign-in'>
            <h2>I already have a account</h2>
            <span>Sign in with your email and password</span>
            <form onSubmit={this.handleSubmit}>
                <FormInput label='email' type="text" name='email' value = {this.state.email} handleChange={this.handleChange} required/>
                <FormInput label='password' type="password" name='password' value = {this.state.password} handleChange={this.handleChange} required/>

                <CustomButton type="submit">SIGN IN</CustomButton>
            </form>
        </div>
    );
}

这样就完成了登录页面的编写, 下边要来使用FireBase的认证功能来完成登录功能了.