不要因為別人的評價而改變自己的想法,因為你的生活是你自己的。 1. React 中 Ref 的應用 1.1 給標簽設置 ref 給標簽設置 ref,ref="username", 通過 this.refs.username 可以獲取引用的標簽,ref 可以獲取到應用的真實 Dom 節點。但是 thi ...
不要因為別人的評價而改變自己的想法,因為你的生活是你自己的。
1. React 中 Ref 的應用
1.1 給標簽設置 ref
給標簽設置 ref,ref="username", 通過 this.refs.username 可以獲取引用的標簽,ref 可以獲取到應用的真實 Dom 節點。但是 this.refs 已被廢棄。
import React, { Component } from "react";
class App extends Component {
render() {
return (
<div>
<input ref="oref"/>
<button onClick={ ()=>{ console.log("value:", this.refs.oref.value) } }>Add</button>
</div>
)
}
}
export default App;
1.2 給組件設置 ref
同上標簽設置 ref 給組件設置 ref 也保持一致,ref="username", 通過 this.refs.username 可以獲取到組件對象。
1.3 新的語法設置 ref
通過定義一個引用屬性 myRef = React.createRef(),通過 this.myRef.current 可以獲取到標簽的真實 Dom 節點以及對應的組件對象。
import React, { Component } from "react";
class App extends Component {
myRef = React.createRef()
render() {
return (
<div>
<div>
<input ref="oref"/>
<button onClick={ ()=>{ console.log("value:", this.refs.oref.value) } }>Add1</button>
</div>
<div>
<input ref={ this.myRef } />
<button onClick={ ()=>{ console.log("value:", this.myRef.current.value) } }>Add2</button>
</div>
</div>
)
}
}
export default App;
2. 引用傳送 forwardRef
引用傳送(Ref forwarding)是一種通過組件向子組件自動傳遞引用 ref 並可以轉發 ref 屬性的技術。當父組件需要得到子組件的元素時,可以利用 forwardRef 來實現。
React.forwardRef 會創建一個 React 組件,這個組件能夠將其接受的 ref 屬性轉發到其組件樹下的另一個組件中。
對於應用者的大多數組件來說沒什麼作用。但是對於有些重覆使用的組件,可能有用。例如某些 input 組件,需要控制其 focus,本來是可以使用 ref 來控制,但是因為該 input 已被包裹在組件中,這時就需要使用 Ref forward 來透過組件獲得input 的引用,可以透傳多層。
應用場景:
ref 的作用是獲取實例,可能是 DOM 實例,也可能是 ClassComponent 的實例。
為什麼需要 forwardRef,我們看一個 React 報錯:
Warning: Function components cannot be given refs.
Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
大致的意思是,函數組件不能直接通過 useRef 引用,應該使用 React.forwardRef 對函數組件進行包裹在進行引用。
一個 Function Component,是沒有實例的(PureComponent),此時用 ref 去傳遞會報錯。
React.forwardRef 會創建一個 React 組件,這個組件能夠將其接受的 ref 屬性轉發到其組件樹下的另一個組件中。這種技術並不常見,但在以下兩種場景中特別有用:
- 轉發 refs 到 DOM 組件;
- 在高階組件中轉發 refs;
此時 React 會將外部 ref,當做參數進行傳入,我們就可以將 ref 放入到我們要引用的對象上面。
註意: React 並沒有將外部 ref 屬性放入 props 中。
普通用法:
import React, { Component } from 'react'
export default class App extends Component {
mytext=null
render() {
return (
<div>
<button type="button" onClick={()=>{
console.log(this.mytext);
this.mytext.current.focus()
this.mytext.current.value="2222"
}}>獲取焦點</button>
<Child callback={(el)=>{
console.log(el);、
//el是臨時變數,用全局的去接這個值
this.mytext=el
//console.log(el.current);
}}/>
</div>
)
}
}
class Child extends Component {
mytext = React.createRef();
//組件渲染完了執行
componentDidMount() {
this.props.callback(this.mytext);
}
render() {
return (
<div style={{background:"yellow"}}>
<input defaultValue="1111" ref={this.mytext}></input>
</div>
);
}
}
使用 forwardRef:
import React, { Component,forwardRef } from 'react'
export default class App_forwardRef extends Component {
mytext=React.createRef()
render() {
return (
<div>
<button type="button" onClick={()=>{
console.log(this.mytext);
this.mytext.current.value="2222"
}}>獲取焦點</button>
<Child ref={this.mytext}/>
</div>
)
}
}
// 這裡Child是函數式組件
// 1、當我們試圖給函數式組件給予ref屬性的時候,會發現並不支持;
// 2、此時需要將子組件用forwardRef進行包裹,它的第二個參數即為我們所需要的元素,當拿到子組件元素的時候,則父組件可以利用此元素對子組件進行操作;
const Child=forwardRef((props,ref)=>{
return (
<div>
<input defaultValue="11111" ref={ref}></input>
</div>
);
})