react入门(三):state、ref & dom简解
一、状态
自己在组件内部定义的
作用:组件内部的状态重新更新时,可以控制组件内部重新渲染(不需要重新调取组件也可以重新渲染)
import React from 'react'; class Clock extends React.Component{ constructor(){ super(); this.state = { time: new Date().toLocaleString(), num: 0 } } componentDidMount() { /** * 修改状态的两种方式 * 1.通过this.setState来修改状态属性 * 2.通过this.forceUpdate来强制渲染 */ setInterval(()=>{ //这种方式不仅能修改状态,还能重新渲染组件。 this.setState({ time: new Date().toLocaleString() }) //这种方式能修改状态,但是不能重新渲染组件。如果要渲染,则需要this.forceUpdate()强制渲染。 this.state.time = new Date().toLocaleString(); this.forceUpdate(); }, 1000) }
render() { return ( <div> <h2>{this.state.time}</h2> <button onClick={event => { //此处setState修改组件的状态是异步编程:执行完setState后,会把修改状态和通知组件渲染的操作放到EventQueue(等待事件队列中),当后面的主栈任务完成才会执行这个操作。 //但setState不全是异步操作。 this.setState({ num: this.state.num+1 }); console.log(this.state.num); //第一次打印的是0 }}>点我</button> </div> ) } } export default Clock;
二、ref & dom
class Clock extends React.Component{ constructor(){ super(); this.state = { time: new Date().toLocaleString(), num: 0 } this.time = React.createRef(); //第三种通过函数创建一个 } componentDidMount() { setInterval(()=>{ /** * 如果我们给元素设置ref属性(属性值是唯一的) * ref="xxx",react在解析jsx的时候,会把所设置的这个属性的元素以对象键值对的方式增加到当前实例的refs对象中{xxx:元素} * 在jsx渲染完成后,想要操作这个元素,直接基于this.refs.xxx就可以获取到,这就是react中的dom操作. */ this.refs.time.innerHTML = new Date().toLocaleString(); //console.log(this.refs) {time: h2} this.time.innerHTML = new Date().toLocaleString(); // console.log(this.time) {time: h2}
}, 1000) } render() { // 第一种(直接定义属性) return <h2 ref={'time'}>{this.state.time}</h2> //第二种(通过箭头函数定义) //ref的值除了是字符串外,还可以是函数。如果是函数,参数x代表的就是当前元素本身,而我们一般会把当前元素直接挂载到实例上, // 以后直接this.xxx就可以操作元素了(例如:这里的x就是h2) return ( <div> <h2 ref={x => {this.time = x}}>{this.state.time}</h2> </div> ) //第三种(通过React.createRef()方法定义) <h2 ref={this.time}>{this.state.time}</h2> } }
下面是几个适合使用 refs 的情况:
- 处理焦点、文本选择或媒体控制。
- 触发强制动画。
- 集成第三方 DOM 库
例如:处理焦点
class CustomTextInput extends React.Component { constructor(props) { super(props); // 创建 ref 存储 textInput DOM 元素 this.textInput = React.createRef(); this.focusTextInput = this.focusTextInput.bind(this); } focusTextInput() { // 直接使用原生 API 使 text 输入框获得焦点 // 注意:通过 "current" 取得 DOM 节点 this.textInput.current.focus(); } render() { // 告诉 React 我们想把 <input> ref 关联到构造器里创建的 `textInput` 上 return ( <div> <input type="text" ref={this.textInput} /> <input type="button" value="Focus the text input" onClick={this.focusTextInput}/> </div> ); } }