17.React学习笔记.受控非受控组件

一. refs的使用##

React开发模式中,通常情况不需要,也不建议直接操作DOM元素,但是某些特殊的情况,确实需要获取到DOM进行某些操作。

  • 管理焦点,文本选择/媒体播放;
  • 触发强制动画;
  • 集成第三方DOM库。
    如何创建refs来获取对应的DOM?三种方式。

1.1 创建方式

import React, { PureComponent, createRef } from 'react'
export default class App extends PureComponent {
  constructor(props) {
    super(props);
    // 方法二
    this.titleRef = createRef();
    // 方法三
    this.titleEl = null;
  }
  render() {
    return (
      
{/*

Hello World

*/}

Hello React

{/* 2. 目前React推荐的方式 */}

Hello React

{/* 3. */}

{ this.titleEl = arg }}>Hello React

) } changeText() { // 1. 使用方式一:字符串(不推荐,后续可能删除) this.refs.titleRef.innerHTML = "Hello wwq" // 2. 使用对象(推荐) this.titleRef.current.innerHTML = "Hello wwq" // 3. 使用回调函数 console.log(this.titleEl); this.titleEl.innerHTML = "Hello jsx3" } }
  • 传入字符串
    - 传入一个对象,官方推荐,取的时候要导入createRef库,用其实例的current属性。
  • 传入回调函数

1.2 ref节点类型

  • ref用于html元素时,构造函数中使用React.createRef()创建的ref接收底层DOM元素作为其current属性

  • ref用于自定义class组件时,ref对象接收组件的挂载实例作为其current属性

  • 不能在函数组件上使用ref属性,因为他们没有实例。

  • 但有时,我们想要获取函数组件中的某个DOM元素。

  • 这个时候我们可以通过React.forwardRef,之后学习hooks中使用refs。

二. 受控组件##

2.1 认识受控组件

  • 在React中,HTML表单的处理方式和普通的DOM元素不太一样;表单元素通常会保存在一些内部的state。
  • HTML中,(input, textarea, select)之类的表单元素通常自己维护state,并根据用户输入进行更新。
  • 而在React中,可变状态mutable state通常保存在组件的state属性中,并且只能通过使用setState()来更新。
    • 我们将两者结合起来,使React的state成为“唯一数据源”;
    • 渲染表单的React组件还控制着用户输入过程中表单发生的操作;
    • React以这种方式控制取值的表单输入元素就叫做“受控组件”

2.1.1 默认提交表单方式
2.2 常见表单的处理

  • 通过给form绑定onSubmit事件来更改默认行为。
  • 给input绑定onChange事件来监听输入变化。
  • 为了输入框和state中数据保持一致,我们需要同步到value,单向数据流:input中输入,触发onChange -> onChange调用handleChange方法更新state -> state中的数据赋给input的value。
import React, { PureComponent } from 'react'
export default class App extends PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      username: "",
    }
  }
  render() {
    return (
      
this.handleSubmit(e)}> {/* label & htmlFor 聚焦 */}
) } handleSubmit(event) { event.preventDefault(); } handleChange(event) { console.log(event.target.value); this.setState({ username: event.target.value, }) } }
  • 如上综合称为受控组件,这时候只需要提交state中的数据即可。


    image.png

2.2.1 textarea标签

2.2.2 select标签

import React, { PureComponent } from 'react'
export default class App extends PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      fruits: "orange",
    }
  }
  render() {
    return (
      
this.handleSubmit(e)}>
) } handleSubmit(event) { event.preventDefault(); console.log(this.state.fruits); } handleChange(event) { console.log(event.target.value); this.setState({ fruits: event.target.value, }) } }

2.2.3 处理多个输入

import React, { PureComponent } from 'react'

export default class App extends PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      username: "",
      password: "",
      valid: "",
    }
  }
  render() {
    return (
      
this.handleSubmit(e)}> {/* label & htmlFor 聚焦 */}

) } handleSubmit(event) { event.preventDefault(); const {username,password,valid} = this.state; console.log(username,password,valid); } handleChange(event) { // 计算属性名 this.setState({ [event.target.name]: event.target.value, }) } }

三. 非受控组件 (不推荐)

  • 推荐:大多数情况使用受控组件
  • 一个受控组件中,表单数据是有React组件来管理的;
  • 另一种方式是非受控组件,这时表单数据将交由DOM节点来处理;
  • 非受控组件中,通过ref来从DOM节点中获取表单数据。
import React, { PureComponent,createRef } from 'react'
export default class App extends PureComponent {
  constructor(props) {
    super(props);
    this.usernameRef = createRef();
  }
  render() {
    return (
      
this.handleSubmit(e)}>
) } handleSubmit(event) { event.preventDefault(); console.log(this.usernameRef.current.value); } }

你可能感兴趣的:(17.React学习笔记.受控非受控组件)