通过 cloneElement reactjs 传递 forwardRef

Dha*_*ala 6 javascript reactjs

const ref = useRef()  

 React.Children.map(this.props.children, (element) => {
   React.cloneElement(element, { 
     innerRef: node => ref,
   })
 })
Run Code Online (Sandbox Code Playgroud)

这里元素是一个组件

像下面这样

const newComponent = forwardRef(({children, ...otherprops}, ref){
    return (
     <div {...otherprops} ref={otherprops.innerRef}>
       {children}
     </div>
    )        
})
Run Code Online (Sandbox Code Playgroud)

得到refnull在 forwardRef ...

可重现的示例:- https://codesandbox.io/s/forward-ref-cloneelement-1msjp

Den*_*ash 6

尝试更改innerRefref,您添加innerRef属性并期望它在以下时间有效ref

import React, { useRef } from 'react';

function RefForm(props) {
  const setRefs = useRef(new Map()).current;
  const { children } = props;
  return (
    <div>
      {React.Children.map(children, child => {
        return React.cloneElement(child, {
//         v not innerRef
          ref: node => {
            console.log('imHere');
            return !node
              ? setRefs.delete(child.key)
              : setRefs.set(child.key, node);
          }
        });
      })}
    </div>
  );
}

export default RefForm;
Run Code Online (Sandbox Code Playgroud)

然后,您可以根据需要超出 ref:

const Email = React.forwardRef((props, ref) => {
  console.log('email--', ref);
  ref(); // logs "imHere"
  return (
    <div style={{ marginTop: '30px' }}>
      <label>this is email</label>
      <input name="email" ref={props.innerRef} />
    </div>
  );
});
Run Code Online (Sandbox Code Playgroud)

编辑前向引用克隆元素

编辑:

对于类组件需要使用另一个键 thenref

上面的例子有一个警告:refs 不会被传递。那是因为 ref 不是道具。和 key 一样,React 对它的处理方式也不同。如果向 HOC 添加 ref,则 ref 将引用最外层的容器组件,而不是包装的组件。

// class component
class Name extends Component {
  render() {
    console.log('name--', this.props.innerRef);

    return (
      <div style={{ marginTop: '30px' }}>
        <label>this is name</label>
        <input name="name" ref={this.props.innerRef} />
      </div>
    );
  }
}

// functional component
const Email = props => {
  console.log('email--', props.innerRef);
  return (
    <div style={{ marginTop: '30px' }}>
      <label>this is email</label>
      <input name="email" ref={props.innerRef} />
    </div>
  );
};

// cloneElement
function RefForm(props) {
  const setRefs = useRef(new Map()).current;
  const { children } = props;
  return (
    <div>
      {React.Children.map(children, child => {
        return React.cloneElement(child, {
          innerRef: node => {
            return !node
              ? setRefs.delete(child.key)
              : setRefs.set(child.key, node);
          }
        });
      })}
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

编辑 Q-58803654-forwardRefInClass