網站首頁 編程語言 正文
Refs轉發
概述
- 將ref自動地通過組件傳遞到子組件的技巧
- 父組件可以通過ref操作子組件,直接使用子組件的DOM
轉發refs到DOM組件
渲染原生 DOM 元素 button 的 FancyButton 組件(子組件)
function FancyButton(props) {
return (
<button className="FancyButton">
{props.children}
</button>
)
}
Ref 轉發是一個可選特性,其允許某些組件接收 ref,并將其向下傳遞給子組件
//子組件
const FancyButton = React.forwardRef((props, ref) => (
<button ref={ref} className="FancyButton">
{props.children}
</button>
))
//父組件
//可以直接獲取 DOM button 的 ref:
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;
//這樣,在父組件中可以直接使用DOM button
以下是對上述示例發生情況的逐步解釋:
- 通過調用 React.createRef 創建了一個 React ref 并將其賦值給 ref 變量
- 指定 ref 為 JSX 屬性,將其向下傳遞給 FancyButton React
- 傳遞ref給forwardRef作為其第二個參數
- 向下轉發ref參數到button,并將其指定為JSX屬性
- 當ref掛載完成,ref.current將指向button DOM節點
組件庫維護者的注意事項
當使用forwardRf時,應將其視為一個新的主版本
在高階組件中轉發refs
轉發ref對高階組件是很有用的,讓我們從一個輸出組件props到控制臺的高階組件為例
function logProps(WrappedComponent) {
class LogProps extends React.Component {
componentDidUpdate(prevProps) {
console.log('old props:', prevProps);
console.log('new props:', this.props);
}
render() {
return <WrappedComponent {...this.props} />;
}
}
return LogProps;
}
logProps組件是一個高階組件,props將會傳遞到其包裹的組件。這個高階組件可以記錄所有傳遞到fancyButton組件的props
class FancyButton extends React.Component {
focus() {
// ...
}
// ...
}
// 我們導出 LogProps,而不是 FancyButton。
// 雖然它也會渲染一個 FancyButton。
export default logProps(FancyButton)
需要注意:refs 將不會透傳下去。這是因為 ref 不是 prop 屬性。就像 key 一樣,其被 React 進行了特殊處理
如果對 HOC 添加 ref,該 ref 將引用最外層的容器組件,而不是被包裹的組件
意味著用于我們 FancyButton 組件的 refs 實際上將被掛載到 LogProps 組件
import FancyButton from './FancyButton';
const ref = React.createRef();
// 我們導入的 FancyButton 組件是高階組件(HOC)LogProps。
// 盡管渲染結果將是一樣的,
// 但我們的 ref 將指向 LogProps 而不是內部的 FancyButton 組件!
// 這意味著我們不能調用例如 ref.current.focus() 這樣的方法
<FancyButton
label="Click Me"
handleClick={handleClick}
ref={ref}
/>;
解決辦法:可以使用 React.forwardRef API 明確地將 refs 轉發到內部的 FancyButton 組件。React.forwardRef 接受一個渲染函數,其接收 props 和 ref 參數并返回一個 React 節點
function logProps(Component) {
class LogProps extends React.Component {
componentDidUpdate(prevProps) {
console.log('old props:', prevProps);
console.log('new props:', this.props);
}
render() {
const {forwardedRef, ...rest} = this.props;
// 將自定義的 prop 屬性 “forwardedRef” 定義為 ref
return <Component ref={forwardedRef} {...rest} />;
}
}
// 注意 React.forwardRef 回調的第二個參數 “ref”。
// 我們可以將其作為常規 prop 屬性傳遞給 LogProps,例如 “forwardedRef”
// 然后它就可以被掛載到被 LogProps 包裹的子組件上。
return React.forwardRef((props, ref) => {
return <LogProps {...props} forwardedRef={ref} />;
});
}
在 DevTools 中顯示自定義名稱
下面的組件將在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);
}
原文鏈接:https://blog.csdn.net/xbczrz/article/details/128083925
相關推薦
- 2022-08-03 Android開發手冊自定義Switch開關按鈕控件_Android
- 2022-07-23 C++數據結構之搜索二叉樹的實現_C 語言
- 2024-02-16 SpringBoot 事務的屬性rollbackFor 與 propagetion
- 2023-03-22 教你利用Golang可選參數實現可選模式_Golang
- 2022-02-14 taro將頁面滾動到指定位置
- 2022-05-15 Qt中QPixmap、QImage、QPicture、QBitmap四者區別詳解_C 語言
- 2022-12-14 深入了解Rust中trait的使用_Rust語言
- 2023-04-17 淺談Golang數據競態_Golang
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支