ref轉發是將ref自動地經過傳遞到其一子組件的技巧,在可重用的組件庫頗有用。經常使用來獲取內部DOM元素的refreact
// 理想狀態下
function FancyButton(props) {
return (
<button className="fancyButton"> {props.children} </button>
)
}
// 其餘使用FancyButton的組件一般不須要獲取內部的DOM元素button的ref,防止組件過分依賴I其餘組件的DOM結構
// 可是這種對comment這樣的應用及組件是很理想的,可是對於Fncybutton或MyTextInput這樣的高可複用"葉"組件來講是很是不方便的,
// 這些組件在整個應用中以一種常似常規的DOM button和input的方式被使用,而且訪問其DOM節點對管理焦點,選中或動畫來講是不可避免的
複製代碼
Ref轉發是一個可選特性,其容許某些組件接受ref,並將其向下傳遞給子組件app
import React, { Component } from 'react'
class LogInfo extends Component {
constructor(props) {
super(props);
this.ref = React.createRef();
this.ref2 = React.createRef()
}
componentDidMount() {
this.ref2.current.style = 'background: #000;color: #fff;border: none; outline: none;'
}
render() {
return (
<div> <FancyButton ref={this.ref2}>Click me!</FancyButton> <p ref={this.ref}>test</p> </div>
)
}
}
const FancyButton = React.forwardRef((props, ref) => {
return (
<div style={{background: 'red',padding: '20px'}}> <button className="fancyButton" ref={ref}> {props.children} </button> </div>
)
})
export default LogInfo;
複製代碼
高階組件透傳全部props到其包裹的組件,全部渲染結果是同樣的,可是並非全部能經過props訪問到的值均可以透傳,ref,key這類通過react處理過到props的屬性就不能透傳,經過refs轉發,既React.forwardRef實現ref組件內傳遞,在高階組件須要處理的內部組件接受在傳遞給返回的組件函數
function logProps(Component) {
class LogProps extends React.Component {
componentDidUpdate(prePorps) {
console.log('pre props', prePorps);
console.log('ew props', this.props);
}
render() {
const { forwardedRef, ...rest } = this.props;
return (
<div>
<Component ref={forwardedRef} {...rest} />
</div>
)
}
}
return React.forwardRef((props, ref) => {
return (
<LogProps forwardRef={ref} { ...props } />
)
})
}
複製代碼
// 如下組件將在 DevTools 中顯示爲 「ForwardRef」:
const WrappedComponent = React.forwardRef((props, ref) => {
return <LogProps {...props} forwardedRef={ref} />;
});
// 若是你命名了渲染函數,DevTools 也將包含其名稱(例如 「ForwardRef(myFunction)」):
const WrappedComponent = React.forwardRef(
function myFunction(props, ref) {
return <LogProps {...props} forwardedRef={ref} />;
}
);
// 設置函數的 displayName 屬性來包含被包裹組件的名稱:
function logProps(Component) {
class LogProps extends React.Component {
// ...
}
function forwardRef(props, ref) {
return <LogProps {...props} forwardedRef={ref} />;
}
// 在 DevTools 中爲該組件提供一個更有用的顯示名。
// 例如 「ForwardRef(logProps(MyComponent))」
const name = Component.displayName || Component.name;
forwardRef.displayName = `logProps(${name})`;
return React.forwardRef(forwardRef);
}
複製代碼