Refs
允许访问真实的DOM
- React数据流 -> 通过 props来实现父子组件的交互
- Refs允许我们用于强制修改子组件
管理input
通过一个按钮清空input的value,并聚焦
import React, { Component, createRef } from 'react'
class MyInput extends Component {
constructor(props) {
super(props)
this.inputRef = createRef()
}
inputClear() {
// => input的dom元素
const inputDom = this.inputRef.current
inputDom.value = ''
inputDom.focus()
}
render() {
return (
<div>
<input type="text" ref={ this.inputRef }/>
<button onClick={ this.inputClear.bind(this) }>操控</button>
</div>
)
}
}
export default class App extends Component {
render() {
return (
<div>
<MyInput />
</div>
)
}
}
点击操作按钮后
- 媒体管理 播放暂停等
- 强制动画
import React, { Component, createRef } from 'react'
class MyBox extends Component {
constructor(props) {
super(props)
this.boxRef = createRef()
}
boxExtend(w, h) {
const oBox = this.boxRef.current
oBox.style.width = w +'px'
oBox.style.height = h +'px'
}
render() {
return (
<>
<div
ref={this.boxRef}
style={{
marginLeft: '100px',
width: 200 + 'px',
height: 200 + 'px',
background: 'orange',
transition: 'all 1s'
}}></div>
<button onClick={ this.boxExtend.bind(this, 500, 500) }>big</button>
<button onClick={ this.boxExtend.bind(this, 200, 200) }>init</button>
</>
)
}
}
export default class App extends Component {
render() {
return (
<div>
<MyBox />
</div>
)
}
}
- 集成第三方dom库 如jq
- 在index.html引入jq的cdn地址
import React, { Component, createRef } from 'react'
class MyBox extends Component {
constructor(props) {
super(props)
this.boxRef = createRef()
}
boxExtend(w, h) {
// => dom节点变成jq对象
const $box = $(this.boxRef.current)
$box.animate({
width: w + 'px',
height: h + 'px'
})
}
render() {
return (
<>
<div
ref={this.boxRef}
style={{
marginLeft: '100px',
width: 200 + 'px',
height: 200 + 'px',
background: 'orange'
}}></div>
<button onClick={ this.boxExtend.bind(this, 500, 500) }>big</button>
<button onClick={ this.boxExtend.bind(this, 200, 200) }>init</button>
</>
)
}
}
export default class App extends Component {
render() {
return (
<div>
<MyBox />
</div>
)
}
}
效果如上面的类似
- model框展示
下面这种方式操作起来多余了一点
import React, { Component, createRef } from 'react'
class Models extends Component {
constructor(props) {
super(props)
this.modelRef = createRef()
if(props.onRef) {
props.onRef(this)
}
}
// 打开模态框
open() {
this.modelRef.current.style.display = 'block'
}
// 关闭模态框
close() {
this.modelRef.current.style.display = 'none'
}
render() {
return (
<div
ref={this.modelRef}
style={{
width: '500px',
border: '1px solid #000',
display: 'none'
}}>
<h1>This is a Model</h1>
<p>this is a super Model</p>
</div>
)
}
}
export default class App extends Component {
model=null
modelOpen(status) {
switch(status) {
case 'open':
this.model.open();
break;
case 'close':
this.model.close();
break;
default:
break;
}
}
render() {
return (
<div>
{/* <MyInput /> */}
<Models onRef={ (instance) => this.model = instance }/>
<button onClick={ () => this.modelOpen('open') }>open</button>
<button onClick={ () => this.modelOpen('close') }>close</button>
</div>
)
}
}
- 合理处理方式
利用状态提升能不使用ref的尽量不要区使用ref,违背react的初衷,而且组件的可配置性变强了
import React, { Component } from 'react'
class Models extends Component {
render() {
console.log(this.props.isOpen)
return (
<div
style={{
width: '500px',
border: '1px solid #000',
display: this.props.isOpen ? 'block' : 'none'
}}>
<h1>This is a Model</h1>
<p>this is a super Model</p>
</div>
)
}
}
export default class App extends Component {
state = {
isOpen: false
}
modelOpen(status) {
this.setState({ isOpen: status === 'open' ? true : false })
}
render() {
return (
<div>
<Models isOpen={ this.state.isOpen }/>
<button onClick={ () => this.modelOpen('open') }>open</button>
<button onClick={ () => this.modelOpen('close') }>close</button>
</div>
)
}
}