React forwardRefの使い方と注意点

6626 ワード

以前はreact.forwardRefを使っていましたが、react高次のコンポーネントにはなかなか応用できませんでした。最近やっとドラムができました。記録しました。重要な点はReact.forwardRefのAPIの中でrefはReactコンポーネントではなくdom要素を指すべきです。
React.forwardRef使用例
次に、Reactコンポーネントに適用されたエラーの例を示します。

const A=React.forwardRef((props,ref)=><B {...props} ref={ref}/>)
これは私が以前よく犯したミスです。ここのrefは有効ではありません。
前に述べたように、refはdom元素を指す必要があります。

const  A=React.forwardRef((props,ref)=>(
<div ref={ref}>
<B {...props} />
</div>
))
作用と注意点
  • 親コンポーネントは、サブアセンブリのDom要素またはクラス構成要素
  • に結合されたrefオブジェクトを作成する。
  • 関数構成要素は、インスタンスなしの
  • である。
  • 高次コンポーネントは特殊処理が必要です。
    親コンポーネントは、サブアセンブリのDom要素の例を取得する。
    在这里插入图片描述
    
    import React, { useRef } from 'react';
    import Content from './content';
    
    const Home = () => {
      //     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);
    親コンポーネントは、サブコンポーネントのクラスコンポーネントの例を取得します。
    在这里插入图片描述
    
    import React, { useRef } from 'react';
    import Content from './content';
    
    const Home = () => {
      //     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>
        )
      }
    };
    高次コンポーネントの中の特殊な状況
    高次コンポーネントは、受信したすべてのプロpsを、包装されたコンポーネントに伝達する。
    refはkeyと似ています。プロではないので、外部の包装容器に紐付けされます。
    
    /*
        ref
      e.g. Hoc1(Hoc2(Content))
    
      <Content ref={myRef} />  Content   ref    Hoc1 ,         
    
            React.forwardRef ===============
    
            Hoc1    React.forwardRef() ref   , props   ref
          0.          forwardRef,    ref,    props(xxx={ref}),      props.xxx  
          1.      ref={XXXX}  //            
          2.  forwardRef         ref
          3.       props,      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 = React.memo(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 forwardRefの使い方と注意点の詳細です。React forwardRefに関する資料は他の関連記事に注目してください。