前端随心记---------React之组件

受控组件和非受控组件

import React, { Component } from 'react'

export default class Forms extends Component {
    // 状态 自己的数据
    constructor(props) {
        super(props);

        // 定义状态
        this.state = {
            username: ''
        }
    }

    // 确保this指向为当前的组件对象
    clickHandler = () => {
        console.log('clickHandler call...');

        // 我们可以给 chrome 浏览安装 react developer tools 插件,帮组我们调试 react 项目
        // this.state.username = 'new name';
        // 尝试修改状态的值,因为状态的值变了,则表单空间的值也要变化。
        // 这种修改不会触发视图的变化。 react建议使用 setState 方法修改
        // console.log(this.state); // 看一下上面的操作是否真的有修改 username 的值

        // 注意事项:1. 我们把需要更改的状态,直接对象传递即可。特点:1. 如果原先的state 里面存在该属性,则覆盖;如果不存在,则添加。如果我们对state里面的属性没有操作,则会保留

        // 状态的变化引发了视图的变化,则我们叫做 单向数据流(之前的 vuejs 也是存在双向数据绑定)方向一
    } 

    changeHandler = (event) => {
        console.log('changeHandler call...');
        console.log(event.target); // 当前操作受控的DOM对象
        console.log(event.target.value); // 受控组件的value值

        // onChange变化---方法二--state--方向一--视图变化(双向数据绑定)
        // 修改状态-->视图
        this.setState({
            username: event.target.value
        })        
        
    }

    getEmailHandler = (event) => {
        console.log(event.target.value);
        
    }

    checkEmailHandler = () =>{

        // 由于我们在非受控组件内部通过 ref 属性传递一个函数,则我们可以直接通过属性读取该DOM ;原先:this.refs.xxx
        console.log( this.myEmail.value );
        return;

        // vuejs 适合前端程序员 react 适合后端程序员  angular 更明显 适合 强类型语言的程序员  c java 

        
        // 校验邮箱  由于是非受控的,则我们没办法通过 state 进行获取。 受控直接 state 即可。 react 对非受控组件提供的DOM的操作,可以获取值 ref属性
        console.log('获取email值');

        var emailVal = document.getElementById('email').value; 
        // 1. 原生的DOM操作。
        // 2. 官方提供了一个DOM操作的封装

        console.log(emailVal);
        // 没有 $ this.$refs
        console.log(this.refs);
        console.log(this.refs.myEmail.value);

        // 可以编写一个 email正则去验证
        // var reg = /^$/i;
        var reg = /^([a-zA-Z]|[0-9])(\w|-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/; 
        // 完全匹配
        if( !reg.test( this.refs.myEmail.value )){
            // console.log('邮箱不合法!');
            window.alert("邮箱不合法!");
            return;
        }

        console.log('邮箱合法');
        ///...................

    } 

    render() {
        return (
            <div>
                <h2>forms组件-受控组件</h2>
                <button type="button" onClick={this.clickHandler}>按钮</button>
                <hr />
                <p>{this.state.username}</p>
                <hr/>
                <label htmlFor="username">用户名:</label>
                {/* 当我们的表单控件的value值和类组件的state进行绑定后,则我们现在的表单控件的行为就收到state的控制,则我们把这个控件叫做 受控组件 */}
                {/* 尝试去修改状态的值,看表单控件里面的值是否发生变化 */}
                {/* 希望我们的受控的组件可以输入信息,则我们需要为受控的组件定义 onChange 事件 */}
                <input type="text" onChange={this.changeHandler}  id="username" value={this.state.username} />

                <hr/>
                <h2>forms组件-非受控组件</h2>
                {/* 表单控件的value值不收到 state 控制 */}
                <label htmlFor="email">邮箱:</label>
                {/* 必须叫 ref 属性的可以随意定 父子通信this.$refs 父找子  子找父 this.$parent  */}
                {/* ref 的值可以是一个字符串,也可以是一个函数 */}
               
                {/* 使用函数的这种写法,相当于在组件内定义一个属性 属性的值为 myEmail ; this.myEmail = 当前DOM对象*/}
                {/* ref 形参代表当前的DOM对象 */}

                <input type="text" ref={ ref => this.myEmail = ref } id="email" onChange={this.getEmailHandler}/>

                <button onClick={this.checkEmailHandler}>校验邮箱是否合法</button>
            </div>
        )
    }
}

猜你喜欢

转载自www.cnblogs.com/hudunyu/p/11809453.html