Tip:还可以只使用箭头函数来绑定 this,就像这样:
class EventDemo1 extends React.Component { state = { name: 'lj' } handleClick() { console.log(typeof this) // 读取状态 console.log(this.state.name) } render() { return ( // 箭头函数 <button onClick={() => this.handleClick()}> click </button> ); } } 使用 preventDefault 阻止默认行为在 html 中我们阻止默认行为可以通过 return false。就像这样:
// 每次点击 button,控制将输出 'You clicked submit.',而不会提交 <body> <form onsubmit="console.log('You clicked submit.'); return false"> <button type="submit">Submit</button> </form> </body>但是在 react 却不能通过返回 false 的方式阻止默认行为。而必须显式的使用 preventDefault。就像这样:
function Form() { function handleSubmit(e) { // 阻止默认行为 e.preventDefault(); console.log('You clicked submit.'); } return ( <form onSubmit={handleSubmit}> <button type="submit">Submit</button> </form> ); } ref我们首先回忆一下 vue 中的 ref:
ref 被用来给元素或子组件注册引用信息 —— vue 官网
引用信息将会注册在父组件的 $refs 对象上。请看示例:
<!-- `vm.$refs.p` will be the DOM node --> <p ref="p">hello</p> <!-- `vm.$refs.child` will be the child component instance --> <child-component ref="child"></child-component>如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例。
那么 react 中的 ref 是否也是这个作用?我们可以从其用法上去做判断。
React 支持一个特殊的、可以附加到任何组件上的 ref 属性。此属性可以是一个由 React.createRef() 函数创建的对象、或者一个回调函数、或者一个字符串(遗留 API) —— 官网-
于是我们知道在 react 中 ref 属性可以是一个对象、回调函数,亦或一个字符串。
String 类型的 Refs下面这个例子将 ref 分别应用在 dom 元素和子组件中:
class ASpan extends React.Component { render() { return <span>click</span> } } class EventDemo1 extends React.Component { handleClick() { console.log(this.refs) console.log(this.refs.aButton.innerHTML) } render() { return ( // 箭头函数 <button ref="aButton" onClick={() => this.handleClick()}> <ASpan ref="aSpan" /> </button> ); } }点击按钮,控制台输出:
{aSpan: ASpan, aButton: button} <span>click</span>Tip:用法上和 vue 中的 vm.$refs 非常相似。
注:如果你目前还在使用 this.refs.textInput 这种方式访问 refs ,我们建议用回调函数或 createRef API 的方式代替 —— 官网-
回调 RefsReact 也支持另一种设置 refs 的方式,称为“回调 refs”。它能助你更精细地控制何时 refs 被设置和解除 —— 官网-回调 Refs
将字符串式 Refs 示例改成回调式。请看示例:
class EventDemo1 extends React.Component { handleClick() { console.log(this.refs) console.log(this.button.innerHTML) } setButtonRef = (element) => { this.button = element } render() { return ( // 使用 `ref` 的回调函数将按钮 DOM 节点的引用存储到 React // 实例上(比如 this.button) <button ref={this.setButtonRef} onClick={() => this.handleClick()}> click </button> ); } }点击按钮,控制台输出:
{} click回调函数中接受 React 组件实例或 HTML DOM 元素作为参数,以使它们能在其他地方被存储和访问。
内联函数可以将 refs 回调函数直接写在 ref 中。就像这样:
// 与上面示例效果相同 <button ref={element => this.button = element} onClick={() => this.handleClick()}> click </button> 回调次数如果 ref 回调函数是以内联函数的方式定义的,在更新过程中它会被执行两次,第一次传入参数 null,然后第二次会传入参数 DOM 元素 —— 官网-关于回调 refs 的说明
请看示例:
class EventDemo1 extends React.Component { state = { date: new Date() } constructor() { super() setInterval(() => { this.setState({ date: new Date() }) }, 3000) } render() { return ( <button ref={element => { this.button = element; console.log('ref'); }}> click {this.state.date.toLocaleTimeString()} </button> ); } }首先输出 ref,然后每过 3 秒就会输出 2 次 ref。
Tip:大多数情况下它是无关紧要的 —— 官网
createRef API将回调 refs 的例子改成 createRef 形式。请看示例:
class EventDemo1 extends React.Component { constructor() { super() this.button = React.createRef() // this.textInput = React.createRef() } handleClick() { // dom 元素或子组件可以在 ref 的 current 属性中被访问 console.log(this.button.current.innerHTML) } render() { return ( <button ref={this.button} onClick={() => this.handleClick()}> click </button> ) } }每点击一下 button,控制台将输出一次 click。