您现在的位置是:网站首页> 编程资料编程资料

React受控组件与非受控组件详细介绍_React_

2023-05-24 212人已围观

简介 React受控组件与非受控组件详细介绍_React_

1. 受控组件

1.1 介绍

概述:

将 state 与表单项中的 value 值绑定在一起,有 state 的值来控制表单元素的值,称为受控组件。

绑定步骤:

  • 在state中添加一个状态,作为表单元素的value值
  • 给表单元素绑定 change 事件,将表单元素的值设置为 state 的值

语法:

# value={this.state.xx} 事件onChange=“方法,修改state中的数据”  注:多表单元素需优化事件方法 this.setState({ [e.target.name]: e.target.value }) 

使用:

import React, { Component } from 'react'; class App extends Component { state = { username: '', password: '' } setValue = name => evt => { this.setState({ // 变量的值当前对象的key,写法 [name]: evt.target.value.trim() }) } login = () => { console.log(this.state); } render() { let { username, password } = this.state return ( 
{/* 表单项中的value值,通过state中的属性值来赋值的,叫受控组件 受控组件: value={this.state.xx} 事件onChange=“方法,修改state中的数据” */}
); } } export default App;

1.2 受控组件简写

同样是实现上面案例中的场景,我们还可以有简写方式。

loginForm.js:

export default _this => ({ username: { value: '', onChange: e => _this.setState(state => ({ username: { ...state.username, value: e.target.value } })) }, password: { value: '', onChange: e => _this.setState(state => ({ password: { ...state.password, value: e.target.value } })) } }) 

App.jsx:

import React, { Component } from 'react'; import loginForm from './form/loginForm'; class App extends Component { state = { ...loginForm(this), num: 100 } login = () => { console.log(this.state); } render() { let { username, password } = this.state return ( 
{/* 相当于 value={username} onChange={this.setValue('username')} */}
); } } export default App;

1.3 在表单中使用受控组件

import React, { Component } from 'react'; class App extends Component { state = { username: '', sex: '女', isshow: true, lessons: ['html', 'js'] } setLessonsFn = e => { if (e.target.checked) { this.setState(state => ({ lessons: [...state.lessons, e.target.value] })) } else { this.setState(state => ({ lessons: state.lessons.filter(item => item != e.target.value) })) } } login = () => { console.log(this.state); } render() { let { username, sex, isshow,lessons } = this.state return ( 
this.setState({ username: e.target.value })} />
{/* 单选 */} this.setState({ sex: e.target.value })} />男 this.setState({ sex: e.target.value })} />女
{/* 单个复选框 */} this.setState({ isshow: e.target.checked })} /> 显示与隐藏
{/* 多个复选框 */}
html css js
); } } export default App;

1.4 综合案例

全选与反选,显示与隐藏的应用

描述:

本案例中我们将要实现,对用户名和密码进行正则验证(账号只能是邮箱或手机号,别的不行;密码必须是3位以上且有数字和字母 ),验证成功后点击登录下方显示用户列表。用户列表有删除功能,有全选和取消全选功能。选中所有的子项,全选就自动勾选,有一个子项没选中,全选就取消勾选 。

实现:

App.jsx:

import React, { Component } from 'react'; import UserTable from './components/UserTable'; class App extends Component { state = { username: '', password: '', show: false, } // 通过onChange事件来修改state中对应属性变化 setUsername = evt => { // console.log(evt.target.value.trim()); this.setState({ username: evt.target.value.trim() }) } setPassword = evt => { this.setState({ password: evt.target.value.trim() }) } setValue = name => evt => { this.setState({ // 变量的值当前对象的key,写法 [name]: evt.target.value.trim() }) } submit = () => { if (this.regExpValue(this.state.username, "username") && this.regExpValue(this.state.password, "password")) { alert("登录成功!") this.login() } else { alert("正则验证失败,请重新输入!") } } regExpValue = (value, key) => { if (key === "username") { return /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/.test(value) || /^1[3-9][0-9]{9}$/.test(value); } else { return /(?=.*?[A-Za-z])(?=.*?[0-9]).{3,}/.test(value); } } login = () => { // this.setState.show=true this.setState({ show: true }); console.log(this.state.show); } render() { let { username, password, show } = this.state return ( 
{/* 表单项中的value值,通过state中的属性值来赋值的,叫受控组件 受控组件: value={this.state.xx} 事件onChange=“方法,修改state中的数据” */}
{ this.state.show ? :
不显示
}
); } } export default App;

UserTable.jsx:

import { getElementError } from '@testing-library/react'; import React, { Component } from 'react'; class UserTable extends Component { state = { users: [ { id: 1, name: '张三' }, { id: 2, name: '李四' }, { id: 3, name: '王五' }, { id: 4, name: '赵六' }, ], isshow: true, uids: [], tip: '全选', } all = e => { e.target.checked ? this.setState(state => ({ uids: state.users.map(({ id }) => id), tip: '取消全选' })) : this.setState({ uids: [], tip: '全选' }) console.log(this.state.uids); } select = tid => e => { let all = document.querySelector(".all"); if (e.target.checked) { setTimeout(() => { this.setState(state => ({ uids: [...state.uids, tid] })) if (this.state.uids.length === 4) all.checked = true }, 0); } else { setTimeout(() => { this.setState(state => ({ uids: state.uids.filter(item => item != tid) })) all.checked = false console.log(this.state.uids); }, 0); } } del = tid => () => { this.setState(state => ({ users: state.users.filter(({ id }) => id !== tid) })) } render() { let { users, uids, tip } = this.state return ( 
{tip}
    { users.map(({ id, name }) => (
  • {name} -- {id}删除
  • )) }
); } } export default UserTable;

2. 非受控组件介绍

概述:

表单项中的 value 或 checked 值,它不受 state 中的属性控制,但是可以而是借助 ref,通过 dom 对象来获取当前表单项中的 value 或 checked 值,这就是非受控组件。

非受控组件的应用的次数没有受控组件多,在工作中,多数使用为受控组件。

注意:react 中如何来获取普通的 html 元素的 dom 对象:ref 对象来获取。

使用步骤:

  1. 调用 React.createRef() 方法创建ref对象
  2. 将创建好的 ref 对象添加到文本框中
  3. 通过ref对象获取到文本框的值

语法:

class App extends React.Component { constructor(props){ super(props) //创建 ref this.username = React.createRef() } // 获取文本框的值 fn =() => { console.log(this.username.current.value) } render(){ return ( 
) } }

示例:

// createRef 通过此方法得到一个ref实例对象 // ref 如果绑定在普通的html元素中则返回dom对象 // ref 如果绑定在"类组件"中,则返回当前自定义类组件实例对象,可以用它来完成组件通信 import React, { Component, createRef } from 'react' class App extends Component { // 创建得到一个ref实例对象 usernameRef = createRef() getUsernameInput = () => { // 通过ref绑定好的对象,来完成对应表单项数据的获取 console.log(this.usernameRef.current.value) } render() { return ( 
) } } export default App

注意:

  1. createRef:通过此方法可以得到一个 ref 实例对象
  2. ref 如果绑定在普通的html元素中则返回dom对象
  3. ref 如果绑定在"类组件"中,则返回当前自定义类组件实例对象,可以用它来完成组件通信

非受控组件的应用

import React, { Component, createRef } from 'react' class App extends Component { // 创建得到一个ref实例对象 usernameRef = createRef() isShowRef = createRef() // 等同于:lessonsRefs = [createRef(), createRef(), createRef()] lessonsRe
                
                

-六神源码网