欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

React操作DOM之forwardRef問題

 更新時間:2023年03月02日 15:27:05   作者:進階的巨人001  
這篇文章主要介紹了React操作DOM之forwardRef問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

React操作DOM之forwardRef

React操作DOM有幾種方式,傳入字符串,傳入一個對象(react推薦的方式),傳入一個函數,今天就講一下使用react封裝過的高階組件forwardRef來操作DOM

首先導入

import React, { PureComponent,createRef,forwardRef } from 'react'

然后const一個函數組件,將它作為App的子組件

const Profile = forwardRef(function (props,ref){
  return <h2 ref={ref}>Profile</h2>
})

定義App組件

export default class App extends PureComponent {
  constructor(props){
    super(props);
    this.profileRef = createRef()
  }
  render() {
    return (
      <div>
        <Profile ref={this.profileRef} name={'lsh'}/>
        <button onClick={e=>this.printRef()}>點擊</button>
      </div>
    )
  }
  printRef(){
    console.log(this.profileRef.current)
  }
}

當我們點擊按鈕時候

用這個的好處是什么?因為我們之前操作dom,函數式組件是不行的,因為它沒有實例,用這個高階組件就能完美解決這個問題

React forwardRef使用方法

作用與注意點

  • 傳遞ref,把自身的ref綁定到其他地方(e.g. 你把文件交給總裁秘書,總裁秘書把文件交給總裁)
  • ref 和 key 有點特殊,不會作為props參數向下傳遞,this.props拿不到ref對象
  • 函數組件是沒有實例的,可以用useImperativeHandle實現(xiàn)部分功能
  • 高階組件需做特殊處理

父 -> 子 -> 子(Dom)

import React, { useRef } from 'react';
import Content from './content';

const Home = () => {
  // 創(chuàng)建一個Ref對象
  const connectRef = useRef(null);

  const handleFoucus = () => {
    const _ref = connectRef.current;
    _ref.focus();
  };

  return (
    <div>
        <button onClick={() => handleFoucus()}>
          使用子組件中DOM元素的方法
        </button>

        <Content ref={connectRef} />
    </div>
  );
};

export default Home;
import React, { forwardRef } from 'react';

/**
 * forwardRef包裹后,ref會作為第二個參數,接收傳進來的ref屬性
 * e.g.
 * <Content count={count} user={user} ref={connectRef}>
 *
 * @param props - {count, user}
 * @param ref   - connectRef
 * */
const Content = (props, ref) => {
  return (
    <div>
   	  {/* 把ref綁定給傳進來的ref ≈ ref={connectRef} */}
      <input type="password" ref={ref} />
    </div>
  )
};

export default forwardRef(Content);

父 -> 子 -> 子(class)

import React, { useRef } from 'react';
import Content from './content';

const Home = () => {
  // 創(chuàng)建一個Ref對象
  const connectRef = useRef(null);

  const handleAdd = () => {
    const _ref = connectRef.current;

    const { count } = _ref.state;
    _ref.setState({
      count: count + 1
    })
  };

  return (
    <div>
        <button onClick={() => handleAdd()}>
          使用子組件中class組件的屬性和方法
        </button>

        <Content ref={connectRef} />
    </div>
  );
};

export default Home;
import React, { forwardRef } from 'react';
import Header from './header';
import Footer from './footer';

/**
 * forwardRef包裹后,ref會作為第二個參數,接收傳進來的ref屬性
 * e.g.
 * <Content count={count} user={user} ref={connectRef}>
 *
 * @param props - {count, user}
 * @param ref   - connectRef
 * */
const Content = (props, ref) => {
  return (
    <div>
      {/* 把ref綁定給傳進來的ref ≈ ref={connectRef} */}
      <Header ref={ref} />  {/* class組件 */}
		
      {/* <Footer ref={ref} /> 函數組件是沒有實例的,所以connectRef.current: null */}
    </div>
  )
};

export default forwardRef(Content)
import React from 'react';

export default class Header extends React.Component {
  state = {
    count: 0
  };

  render() {
    return (
      <div>
        {this.state.count}
      </div>
    )
  }
};

高階組件中的特殊情況

  • 高階組件本質是函數,參數為組件,返回值是新組件(增強過的組件)
  • 高階組件會把所有接收到的props,傳遞給被包裝的組件(透傳)
  • ref 和 key 類似,不是一個prop,所以不會透傳,ref會綁定到外層的高階組件上
  • 高階組件可以嵌套多層,e.g. Hoc1(Hoc2(Hoc3(Content)))

所以為了把ref傳遞給最里面的組件,有兩種方法

  • 在最外層用 forwardRef 對 ref 對象進行處理,ref -> ref -> props.key = ref
  • 不用 ref,用自定義props承載 ref 對象,props.key = ref
/*
  處理ref
  e.g. Hoc1(Hoc2(Content))

  <Content ref={myRef} /> 給Content綁定的ref會綁定到Hoc1上,且不會繼續(xù)向下傳遞

  第一種方法 React.forwardRef ===============

      在 Hoc1外面 用React.forwardRef()對ref做處理,用props來傳遞ref
      0. 在高階組件外面包裹forwardRef,攔截獲取ref,增加一個props(xxx={ref}),真實組件通過props.xxx獲取
      1. 使用時傳 ref={XXXX}  // 和第二種方法不同的地方
      2. 用forwardRef的第二個參數獲取 ref
      3. 增加一個新的props,用來向下轉發(fā)ref  e.g. forwardedRef={ref}
      4. 真實組件中綁定 ref={props.forwardedRef}

      const Home = (props) => {
        const connectRef = useRef(null);

        return (
          <div>
            <Content ref={connectRef} />
          </div>
        );
      };

      // 被包裝組件
      const Content = (props) => {
        return (
          <div>
            <input type="password" ref={props.forwardedRef} />
          </div>
        );
      };


      // forwardRef的第二個入參可以接收ref,在Hoc外層對ref做處理
      export default React.forwardRef((props, ref) => {
        const Wrapper = withRouter(Content);  // Hoc

        // forwardRef包裹的是Wrapper
        // 需要在Wrapper中把ref向下傳遞給真實組件
        // Wrapper中增加一個props屬性,把ref對象作為props傳給子組件
        return <Wrapper {...props} forwardedRef={ref} />;
      });

  第二種方法 ==========

  0. 使用時就用一個props來保存ref
  1. 使用時傳 xxx={ref}  // 和第一種方法的不同點
  2. 真實組件中綁定 ref={props.xxx}

  const Home = (props) => {
    const connectRef = useRef(null);

    return (
      <div>
        <Content forwardedRef={connectRef} />
      </div>
    );
  };

  // 定義高階組件
  export const Hoc = (WrappedComponent) => {
    class Wrapper extends React.Component {
      render() {
        return <WrappedComponent {...props} />
      }
    }
  }

  // 被包裝的組件
  const Content = (props) => {
    return (
      <div>
        <input type="password" ref={props.forwardedRef} />
      </div>
    );
  };

  // 包裝過程
  export default Hoc(Content);

* */

總結

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • React中DOM事件和狀態(tài)介紹

    React中DOM事件和狀態(tài)介紹

    這篇文章主要介紹了React中DOM事件和狀態(tài)介紹,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下
    2022-08-08
  • React中getDefaultProps的使用小結

    React中getDefaultProps的使用小結

    React中的getDefaultProps功能允許開發(fā)者為類組件定義默認屬性,提高組件的靈活性和容錯性,本文介紹了getDefaultProps的作用、語法以及最佳實踐,并探討了其他替代方案,如函數組件中的默認參數、高階組件和ContextAPI等,理解這些概念有助于提升代碼的可維護性和用戶體驗
    2024-09-09
  • 詳解在React中跨組件分發(fā)狀態(tài)的三種方法

    詳解在React中跨組件分發(fā)狀態(tài)的三種方法

    這篇文章主要介紹了詳解在React中跨組件分發(fā)狀態(tài)的三種方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08
  • 基于Webpack4和React hooks搭建項目的方法

    基于Webpack4和React hooks搭建項目的方法

    這篇文章主要介紹了基于Webpack4和React hooks搭建項目的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-02-02
  • React-Native之截圖組件react-native-view-shot的介紹與使用小結

    React-Native之截圖組件react-native-view-shot的介紹與使用小結

    這篇文章主要介紹了React-Native之截圖組件react-native-view-shot的介紹與使用小結,需本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,要的朋友可以參考下
    2021-08-08
  • React如何以Hook的方式使用Echarts

    React如何以Hook的方式使用Echarts

    這篇文章主要介紹了React如何以Hook的方式使用Echarts問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • 在?React?Native?中給第三方庫打補丁的過程解析

    在?React?Native?中給第三方庫打補丁的過程解析

    這篇文章主要介紹了在?React?Native?中給第三方庫打補丁的過程解析,有時使用了某個React Native 第三方庫,可是它有些問題,我們不得不修改它的源碼,本文介紹如何修改源碼又不會意外丟失修改結果的方法,需要的朋友可以參考下
    2022-08-08
  • 在react中使用 indexDb的方法

    在react中使用 indexDb的方法

    在React中使用IndexedDB進行前端離線存儲,可以存儲大量數據,支持復雜的數據類型和高性能查詢,通過示例展示了如何創(chuàng)建數據庫、添加數據、查詢數據和構建一個簡單的待辦事項應用,感興趣的朋友跟隨小編一起看看吧
    2024-11-11
  • React虛擬列表的實現(xiàn)代碼

    React虛擬列表的實現(xiàn)代碼

    最近看了vueuse的useVirtualList的實現(xiàn)方式,發(fā)現(xiàn)虛擬滾動效果不錯,就嘗試著同樣的寫法改成react版本,虛擬列表主要包含三部分組成,offset,viewcapacity,overscan,本文就給大家介紹一下React虛擬列表的實現(xiàn),需要的朋友可以參考下
    2023-08-08
  • 如何用react優(yōu)雅的書寫CSS

    如何用react優(yōu)雅的書寫CSS

    這篇文章主要介紹了如何用react優(yōu)雅的書寫CSS,幫助大家更好的理解和學習使用react,感興趣的朋友可以了解下
    2021-04-04

最新評論