react中受控组件与非受控组件

需求:
  定义一个包含表单的组件
   输入用户名密码后, 点击登录提示输入信息

1、包含表单的组件分类

1.1、受控组件

  受控组件通过event.target获取对应的DOM节点,event.target.value获取节点的值。 通过这种方式实现,类似于vue的双向数据绑定,input 的值 改变了,对应属性也改变;属性值 改变了, input的值也改变。建议使用受控组件,因为非受控组件有对ref的使用,最好不要过渡使用ref。

    //1、创建组件
    class Demo extends React.Component {
        //初始化状态
        state = ({
            userName: '', pwd: ''
        })
        saveUserName = (event) => {
            //    通过event.target获取dom
            this.setState({
                userName: event.target.value
            })

        }
        savePwd = (event) => {
            this.setState({
                pwd: event.target.value
            })
        }
        handleSubmit = (event) => {
            event.preventDefault();//阻止表单提交
            const {userName, pwd} = this.state;
            alert(`用户名${userName},密码${pwd}`);
        }

        render() {
            return (
                <form onSubmit={this.handleSubmit}>
                    用户名:<input onChange={this.saveUserName} type="text" name="userName" id=""/>
                    密码:<input onChange={this.savePwd} type="password" name="password" id=""/>
                    <button>登录</button>
                </form>
            )
        }
    }
    //2、渲染虚拟DOM
    ReactDOM.render(<Demo/>, document.getElementById('test'))

  对上述代码逐步进行优化:

方法1:高阶函数—函数珂里化

  高阶函数:如果一个函数符合下面2个规范中的任何一个,那么函数就是高阶函数:

  1. 若A函数,接收的参数是一个函数,那么A就可以称之为高阶函数
  2. 若A函数,调用的返回值依然是一个函数,那么A就可以称之为高阶函数

  常见的高阶函数有:Promise、 setTimeout、arr.map()…

   函数的珂里化:通过函数调用继续返回调用函数的方式,实现多次接收参数最后统一处理的函数编码形式。

//1、创建组件
    class Demo extends React.Component {
        //初始化状态
        state = ({
            userName: '', pwd: ''
        })
        saveFormDate = (dataType) => {
            //高阶函数-函数珂里化
            return (event) => {
                console.log(event.target.value);
                this.setState({
                    [dataType]: event.target.value
                })
            }
        }
        handleSubmit = (event) => {
            event.preventDefault();//阻止表单提交
            const {userName, pwd} = this.state;
            alert(`用户名${userName},密码${pwd}`);
        }

        render() {
            return (
                <form onSubmit={this.handleSubmit}>
                    用户名:<input onChange={this.saveFormDate('userName')} type="text" name="userName" id=""/>
                    密码:<input onChange={this.saveFormDate('pwd')} type="password" name="password" id=""/>
                    <button>登录</button>
                </form>
            )
        }
    }

    //2、渲染虚拟DOM
    ReactDOM.render(<Demo/>, document.getElementById('test'))

方法2:不用珂里化的方法

 saveFormDate = (dataType, event) => {
            this.setState({
                [dataType]: event.target.value
            })
        }


render() {
            return (
                <form onSubmit={this.handleSubmit}>
                    用户名:<input onChange={event => this.saveFormDate('userName', event)} type="text" name="userName"
                               id=""/>
                    密码:<input onChange={event => this.saveFormDate('pwd', event)} type="password" name="password"
                              id=""/>
                    <button>登录</button>
                </form>
            )
        }

方法3:使用自定义属性data-xxx=‘xxxx’

saveFormDate = (event) => {
            let key=event.target.dataset.key
            this.setState({
                [key]: event.target.value
            })
        }

render() {
            return (
                <form onSubmit={this.handleSubmit}>
                    用户名:<input data-key="userName" onChange={this.saveFormDate} type="text" name="userName"
                               id=""/>
                    密码:<input data-key="pwd" onChange={this.saveFormDate} type="password" name="password"
                              id=""/>
                    <button>登录</button>
                </form>
            )
        }

1.2、非受控组件

  通过ref去获取表单DOM,然后通过DOM获取表单的值,不是通过react事件去控制。

方式1: 字符串形式

const {input1}=this.refs;
<input ref='input1' type='text' />

方式2: 回调函数形式

<input ref={currentNode => this.userName =currentNode } type="text" name="userName"/>

方式3: createRef形式

myRef=React.createRef();
console.log(this.myRef.current.value);
<input type='text' ref={this.myRef}/>
 //创建组件
    class Demo extends React.Component {
        handleSubmit = (event) => {
            event.preventDefault();//阻止表单提交
            const {userName, password} = this;
            alert(`用户名${userName.value},密码${password.value}`);
        }

        render() {
            return (
                <form  onSubmit={this.handleSubmit}>
                    用户名:<input ref={c => this.userName = c} type="text" name="userName" id=""/>
                    密码:<input ref={c => this.password = c} type="password" name="password" id=""/>
                    <button>登录</button>
                </form>
            )
        }
    }

    ReactDOM.render(<Demo/>, document.getElementById('test'))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值