React的refs和表单组件
react中refs的使用字符串形式的ref
react核心就在于虚拟DOM,也就是React中不总是直接操页面的真实DOM元素,并且结合Diffing算法,可以做到最小化页面重绘,但有些时候不可避免我们需要一种方法可以操作我们定义的元素标签,并作出对应的修改,在React中提供了一种访问Dom节点的方式,也就是refs,组件中的标签可以通过定义ref属性来标识自己。
基本使用
import React from "react"
class App extends React.Component{state = {isWash:false}popClick=()=>{console.log("popClick",document.getElementsByTagName("input")[0].value)// console.log(this);const { inputRef } = this.refs;console.log("popClick",inputRef.value)}render(){return(<><input type="text" ref="inputRef" placeholder="请输入内容" /><button onClick={this.popClick}>点击获取内容</button></>)}
}
export default App
react中refs的使用回调形式的ref
在react单项数据流中,props是父组件与子组件交互的唯一方式,要修改一个子组件,一般只能通过props重新渲染,在某些情况下,需要在典型数据流之外强制修改子组件,被修改的子组件可能是一个React组件实例,也可能是一个DOM元素,ref属性附加到React元素上,以便访问。
- 使React.createRef()方法创建一个ref对象实例,附加到HTML元素上,接受底层DOM元素座位其current属性。
- 挂载到Class组件上,其current指向该类组件实例。
- 不能挂载到函数组件上,因为函数组件没有实例。 不仅可以使用react.createRef()方法创建ref实例引用react元素,还可以使用一个回调函数,绑定react元素。
import React from "react"
class App extends React.Component{state = {isWash:false}popClick=()=>{console.log("popClick",this.inputRef.value)}render(){return(<><input type="text" ref={(e)=>{this.inputRef=e}} placeholder="请输入内容" /><button onClick={this.popClick}>点击获取内容</button></>)}
}
export default App
关于回调ref调⽤的次数
如果ref会点函数是以内联函数的方式定义的,在更新过程中它会被执行两次,通过将ref的回调函数定义为class的绑定函数。
import React from "react"
class App extends React.Component {state = { xd: true }popClick = () => {console.log(this.input1.value); }handleClick = () => {this.setState({ state: !this.state.xd });}render() {return <div><inputref={(a) => ((this.input1 = a), console.log(11))}type="text"placeholder="请输⼊内容"/><button onClick={this.popClick}>点击⽣成弹窗</button><button onClick={this.handleClick}>点击更新组件</button></div>}
}
export default App
使用createRef创建ref
createref是使用React.createRef()创建的,并通过ref属性附加到react元素,在构造组件时,通常将refs分配给实例属性,以便在整个组件中引用他们,React.create()调用后可以想象成创建一个容器,这个容器可以存储被ref标识的元素节点,创建一个容器只能绑定一个节点,绑定多个节点会被覆盖。
import React from "react"
class App extends React.Component {state = { xd: true }inputRef = React.createRef()popClick = () => {console.log(this.inputRef.current.value); }handleClick = () => {this.setState({ state: !this.state.xd });}render() {return <div><inputref={this.inputRef}type="text"placeholder="请输⼊内容"/><button onClick={this.popClick}>点击⽣成弹窗</button></div>}
}
export default App
react受控组件和非受控组件
受控组件
React中受控组件是指表单元素的控制交给React,表单元素的值是完全交由组件的state控制。组件内部维护state,state属性和表单元素的值建⽴依赖关系,再通过onChange事件与setState()结合更新state属性,就能达到控制⽤户输⼊过程中表单发⽣的操作,控制取值的表单输⼊元素就叫做受控组件(类似vue的数据双向绑定)
非受控组件
非受控组件是指表单元素的状态并不受React组件状态的影响,表单元素的值存储与DOM元素中,如果要React组件要获取DOM元素的值,需要通过绑定ref的方式去获取。
受控组件示例
import React from "react"
class App extends React.Component {handleSubmit = (e) => {e.preventDefault();console.log(this.name.value);};render() {return <div><form onSubmit={this.handleSubmit}><label>名字:<input type="text" ref={(a) => (this.name = a)} /></label><button type="submit">提交</button></form></div>}
}
export default App
非受控组件示例
import React from "react"
class App extends React.Component {state = { value: "传玉昨天去洗脚了" };handleChange = (event) => {console.log(event.target.value);this.setState({ value: event.target.value });};handleSubmit = (e) => {// 禁⽌表单的默认刷新e.preventDefault();console.log(this.state.value);};render() {return <div><form onSubmit={this.handleSubmit}><label>名字:<inputvalue={this.state.value}type="text"onChange={this.handleChange}/></label><button type="submit">提交</button></form></div>}
}
export default App
剖析React中的Diffing算法
框架中为什么要使用虚拟DOM?Diffing算法原理是什么?
当数据改变时,react会生成新的虚拟dom和旧的虚拟dom进行对比,有不同的节点则重新生成,节点相同则进行复用,不重新生成提高渲染速度。
便利数组渲染数据时,为什么要加key属性,使用index座位key会有什么问题?
key主要用在vue虚拟DOM,类似js对象格式的数据的diff算法,新旧虚拟DOM进行对比,复用不变的旧节点,渲染改变的节点,提高渲染速度,遍历数组不加key属性时,则默认使用数组的索引index,在数组元素顺序打乱时,会产生不必要的DOM更新。key值要使用唯一的id值。
react中的ref使用完结~