ref的作用是讓我們快速的綁定節(jié)點(diǎn)并獲取到節(jié)點(diǎn),三種綁定方式分別是字符串、回調(diào)函數(shù),createRef()
參考
https://www.wekic.com/article/10
使用場景
- 對Dom元素的焦點(diǎn)控制、內(nèi)容選擇、控制
- 對Dom元素的內(nèi)容設(shè)置及媒體播放
- 對Dom元素的操作和對組件實例的操作
- 集成第三方 DOM 庫
1. createRef (類組件)
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
componentDidMount(){
this.myRef.current.focus();
}
render() {
return <Input ref={this.myRef}/>;
}
}
2.useRef (函數(shù)組件)
情況一:直接掛在Dom元素上
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
// `current` 指向已掛載到 DOM 上的文本輸入元素
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}
情況二: 掛載在子組件上
const Child=React.forwardRef((props, ref)=> {
return (
<>
<input type="text" ref={ref}/>
</>
)
})
const Parent = () => {
const ref = React.createRef();
const focus = () => {
ref.current.focus()
}
return (
<>
<Child ref={ref}/>
<button onClick={focus}>獲得焦點(diǎn)</button>
</>
)
}
export default Parent
/*********************************************************************/
useImperativeHandle可以讓你在使用 ref 時自定義暴露給父組件的實例值。在大多數(shù)情況下,應(yīng)當(dāng)避免使用 ref 這樣的命令式代碼。useImperativeHandle 應(yīng)當(dāng)與 forwardRef一起使用
const Child=React.forwardRef((props, ref)=> {
const inputRef=useRef()
useImperativeHandle(ref, () => ({
inputfocus: () => {
inputRef.current.focus()
}
}));
return (
<>
<input type="text" ref={inputRef}/>
</>
)
})
const Parent=()=> {
const ref = useRef();
const focus=()=>{
ref.current.inputfocus()
}
return (
<>
<Child ref={ref}/>
<button onClick={focus}>獲得焦點(diǎn)</button>
</>
)
}
export default Parent
3. refs回調(diào)
https://zh-hans.reactjs.org/docs/refs-and-the-dom.html#callback-refs
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
this.textInput = null;
this.focusTextInput = () => {
// 使用原生 DOM API 使 text 輸入框獲得焦點(diǎn)
if (this.textInput) this.textInput.focus();
};
}
componentDidMount() {
// 組件掛載后,讓文本框自動獲得焦點(diǎn)
this.focusTextInput();
}
render() {
// 使用 `ref` 的回調(diào)函數(shù)將 text 輸入框 DOM 節(jié)點(diǎn)的引用存儲到 React
return (
<input
type="text"
ref={element => this.textInput = element}
/>
);
}
}
export default CustomTextInput
可以在組件間傳遞回調(diào)形式的 refs,就像你可以傳遞通過 React.createRef() 創(chuàng)建的對象 refs 一樣
function CustomTextInput(props) {
return (
<div>
<input ref={props.inputRef} />
</div>
);
}
class Parent extends React.Component {
render() {
return (
<CustomTextInput
inputRef={el => this.inputElement = el}
/>
);
}
}
4.String 類型的 Refs
字符串類型的refs不建議使用它,因為 string 類型的 refs 存在 一些問題。它已過時并可能會在未來的版本被移除
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
this.textInput = null;
this.focusTextInput = () => {
// 使用原生 DOM API 使 text 輸入框獲得焦點(diǎn)
this.refs.textInput.focus()
};
}
componentDidMount() {
// 組件掛載后,讓文本框自動獲得焦點(diǎn)
this.focusTextInput();
}
render() {
return (
<input
type="text"
ref='textInput'
/>
);
}
}
export default CustomTextInput
useRef和createRef的區(qū)別
useRef 一般用于函數(shù)組件
useRef 不僅僅是用來管理 DOM ref 的,它還相當(dāng)于 this , 可以存放任何變量。
當(dāng) useRef 的內(nèi)容發(fā)生變化時,它不會通知您。更改.current屬性不會導(dǎo)致組件重新渲染。因為他一直是一個引用 。createRef一般用于類組件,
React.createRef 創(chuàng)建一個能夠通過 ref 屬性附加到 React 元素的 ref。
如果用于函數(shù)組件中,當(dāng)App這個函數(shù)組件被重新渲染時,App函數(shù)將會執(zhí)行,并且重新創(chuàng)建、初始化所有的變量和表達(dá)式。因此,createRef每次都會被執(zhí)行,所以對應(yīng)的值總是為null。
createRef 每次渲染都會返回一個新的引用,而 useRef 每次都會返回相同的引用。