React文檔篇 - refs轉發

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節點對管理焦點,選中或動畫來講是不可避免的
複製代碼

React.fowardRef

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;
複製代碼

在高階組件轉發refs

高階組件透傳全部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下的React.forward(fn)命名

// 如下組件將在 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);
}
複製代碼
相關文章
相關標籤/搜索