Refs
允许我们访问真实 DOM
一般的,React
数据流是通过 props
来实现父子组件的交互
Refs
允许我们用于强制修改子组件
// 输入框焦点
class MyInput extends React.Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
}
inputOperating() {
console.log(this.inputRef.current.value);
this.inputRef.current.focus();
}
render() {
return (
<div>
<input type="text" ref={this.inputRef} />
<button onClick={this.inputOperating.bind(this)}>获取焦点</button>
</div>
);
}
}
// 媒体管理
class MyVideo extends React.Component {
constructor() {
super();
this.vdoRefs = React.createRef();
}
vdoPause() {
this.vdoRefs.current.pause();
}
vdoPlay() {
this.vdoRefs.current.play();
}
render() {
return (
<div>
<video
ref={this.vdoRefs}
src="http://vjs.zencdn.net/v/oceans.mp4"
controls
autoPlay
muted
></video>
<button onClick={this.vdoPause.bind(this)}>暂停</button>
<button onClick={this.vdoPlay.bind(this)}>播放</button>
</div>
);
}
}
// 操作动画
class MyBox extends React.Component {
constructor(props) {
super(props);
this.boxRef = React.createRef();
}
boxExtend() {
const oBox = this.boxRef.current;
oBox.style.width = "500px";
oBox.style.height = "500px";
}
render() {
return (
<>
<div
ref={this.boxRef}
style={{
width: 200 + "px",
height: 200 + "px",
backgroundColor: "orange",
transition: "all 1s",
}}
></div>
<button onClick={this.boxExtend.bind(this)}>Extend</button>
</>
);
}
}
createRef 用法细节
-
通过 createRef
创建ref
对象 -
通过元素的 ref
属性可以附加到React
元素上 -
一般通过构造器中给 this
赋值一个ref
,方便整个组件使用 -
ref
只要传递React
元素中,就可以利用ref
的current
属性访问到该真实DOM
节点 -
「ref 在 componentDidMount
和componentDidUpdate
触发前更新」
ref
不同的使用方式:
-
ref
放在HTML
元素上,则指向真实DOM
节点 -
ref
放在class
组件上,则指向组件实例<MyBox ref={xxx}/>
-
ref 放在函数组件上,不能增加 ref
属性,可以使用React.useRef()
forwardRef (v16.3 以上版本)
将子组件的 ref
暴露给父组件
React.forwardRef((props, ref) => { return React 元素})
const MyInput = React.forwardRef((props, ref) => (
// ref 参数只能在,用 forwardRef 定义的组件内可接收
<input type="text" placeholder={props.placeholder} ref={ref} />
));
class App extends React.Component {
constructor(props) {
super(props);
this.myInputRef = React.createRef();
}
inputOperate() {
this.myInputRef.current.value = "";
this.myInputRef.current.focus();
}
render() {
return (
<div>
<MyInput placeholder="请输入" ref={this.myInputRef} />
<button onClick={this.inputOperate.bind(this)}>获取焦点</button>
{/* <MyVideo /> */}
{/* <MyBox ref={xxx}/> */}
</div>
);
}
}
// 高阶组件 ref 转发
class MyInput extends React.Component {
render() {
return <input type="text" placeholder={this.props.placeholder} />;
}
}
function InputHoc(WarpperComponent) {
class Input extends React.Component {
render() {
const { forwardRef, ...props } = this.props;
return <WarpperComponent ref={forwardRef} {...props} />;
}
}
function forwardRef(props, ref) {
return <Input forwardRef={ref} {...props} />;
}
// 设置别名
forwardRef.displayName = `Input - ${WarpperComponent.name}`;
return React.forwardRef(forwardRef);
// return React.forwardRef((props, ref) => (
// <Input forwardRef={ref} {...props} />
// ));
}
const MyInputHoc = InputHoc(MyInput);
class App extends React.Component {
constructor(props) {
super(props);
this.myInputRef = React.createRef();
}
componentDidMount() {
console.log(this.myInputRef);
}
inputOperate() {
this.myInputRef.current.value = "";
this.myInputRef.current.focus();
}
render() {
return (
<>
<MyInputHoc ref={this.myInputRef} placeholder="请输入" />
<button onClick={this.inputOperate.bind(this)}>获取焦点</button>
</>
);
}
}
Refs 转发(v16.2 及以下)
-
通过 props 转发
class MyInput extends React.Component {
render() {
return <input type="text" ref={this.props.inputRef} />;
}
}
// 通过 props 转发
class App extends React.Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
}
componentDidMount() {
console.log(this.inputRef);
}
render() {
return (
<div>
<MyInput inputRef={this.inputRef} />
</div>
);
}
}
-
回调 Refs
class App extends React.Component {
constructor(props) {
super(props);
this.inputRef = null;
}
setMyInput(el) {
this.inputRef = el;
}
focusInput() {
this.inputRef.value = "";
this.inputRef.focus();
}
render() {
return (
<div>
<input type="text" ref={this.setMyInput.bind(this)} />
<button onClick={this.focusInput.bind(this)}>click</button>
</div>
);
}
}
-
字符串 refs
(不建议使用)
-
组件实例下面的 refs
集合里的ref
-
需要 React 保持跟踪当前正在渲染的组件, this
没法确定 -
React 获取 ref
可能会比较慢 -
不能在 render 中工作 -
不能组合,只能设置一个 ref
class App extends React.Component {
componentDidMount() {
// 字符串 refs
console.log(this.refs.inputRef);
}
render() {
console.log(this.refs.inputRef); // undefined
return (
<div>
<input type='text' ref='inputRef' />
</div>
);
}
}
原文始发于微信公众号(前端华先生):React 中的 Refs(9)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/55337.html