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);
}
复制代码
相关文章
相关标签/搜索