React Refs的使用
Refs使用场景:
- 管理焦点,文本选择或媒体播放。
- 触发强制动画。
- 集成第三方 DOM 库。
- 访问Dom常用方法
使用 React.createRef() 创建
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
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>
);
}
}
export default CustomTextInput
refs的另一种方法 回调refs
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
this.textInput = null;
this.setTextInputRef = element => {
this.textInput = element;
};
this.focusTextInput = () => {
// 使用原生 DOM API 使 text 输入框获得焦点
if (this.textInput) this.textInput.focus();
};
}
componentDidMount() {
// 组件挂载后,让文本框自动获得焦点
this.focusTextInput();
}
render() {
// 使用 `ref` 的回调函数将 text 输入框 DOM 节点的引用存储到 React
// 实例上(比如 this.textInput)
return (
<div>
<input
type="text"
ref={this.setTextInputRef}
/>
<input
type="button"
value="Focus the text input"
onClick={this.focusTextInput}
/>
</div>
);
}
}
export default CustomTextInput
利用回调ref来控制获取子组件dom
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
function CustomTextInput(props) {
return (
<div>
<input ref={props.inputRef} />
</div>
);
}
class Parent extends React.Component {
inputElement=null
componentDidMount(){
this.inputElement.value="我用ref控制下CustomTextInput"
}
render() {
return (
<CustomTextInput
inputRef={el =>{console.log(el); this.inputElement = el}}
/>
);
}
}
export default Parent
这个相当于把inputRef这个函数作为属性传给CustomTextInput,this还是绑定在父组件,从而间接获取input的ref
默认情况下,你不能在函数组件上使用 ref 属性,因为它们没有实例: 如果要在函数组件中使用 ref,你可以使用 forwardRef(可与 useImperativeHandle 结合使用),或者可以将该组件转化为 class 组件。
refs转发
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
const FancyButton = React.forwardRef((props, ref) => (
<button ref={ref} className="FancyButton" {...props}>
{props.children}
</button>
));
class Parent extends React.Component {
fancyRef = React.createRef();
fancyClick = () => {
console.log("我拿到的是button元素", this.fancyRef.current)
}
render() {
return (
<div>
<FancyButton ref={this.fancyRef} onClick={this.fancyClick} >Fancy Button </FancyButton>
</div>
)
}
}
export default Parent
官方解释:
- 我们通过调用 React.createRef 创建了一个 React ref 并将其赋值给 ref 变量。
- 我们通过指定 ref 为 JSX 属性,将其向下传递给
。 - React 传递 ref 给 forwardRef 内函数 (props, ref) => ...,作为其第二个参数。
- 我们向下转发该 ref 参数到
- 当 ref 挂载完成,ref.current 将指向
注意
第二个参数 ref 只在使用 React.forwardRef 定义组件时存在。常规函数和 class 组件不接收 ref 参数,且 props 中也不存在 ref。
Ref 转发不仅限于 DOM 组件,你也可以转发 refs 到 class 组件实例中。
下面是高阶组件使用Ref转发
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
//这是一个包装函数 能打印出输入的值
const Decorate = InputComponent => {
const forwardRef = (props, ref) => {
const print = () => console.log("ref当前的值", ref.current.value);
return <InputComponent forwardedRef={ref} onChange={print} {...props} />;
};
return React.forwardRef(forwardRef);
};
//包装函数将转发ref属性传给需要包装的组件
const TextInput = ({ forwardedRef, children, ...rest }) => (
<div>
<input ref={forwardedRef} {...rest} />
{children}
</div>);
const InputField = Decorate(TextInput);
class CustomTextInput extends React.Component {
render() {
const inputRef = React.createRef();
return <InputField ref={inputRef}>children</InputField >;
}
}
export default CustomTextInput
最后 勿过度使用Refs 多考虑状态提升,在 React 中,将多个组件中需要共享的 state 向上移动到它们的最近共同父组件中,便可实现共享 state。这就是所谓的“状态提升”。
总之,ref在实际中还是用的不是很多,特别是转发ref的使用,主要借此来记录ref的使用
本文主要参考 官方文档
(完)
0条看法
最新最后最热
等待你的评论