admin管理员组

文章数量:1310004

const ref = useRef()  

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

here element is a ponent

like the following

const newComponent = forwardRef(({children, ...otherprops}, ref){
    return (
     <div {...otherprops} ref={otherprops.innerRef}>
       {children}
     </div>
    )        
})

getting ref is null in forwardRef...

Reproducible example :-

const ref = useRef()  

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

here element is a ponent

like the following

const newComponent = forwardRef(({children, ...otherprops}, ref){
    return (
     <div {...otherprops} ref={otherprops.innerRef}>
       {children}
     </div>
    )        
})

getting ref is null in forwardRef...

Reproducible example :- https://codesandbox.io/s/forward-ref-cloneelement-1msjp

Share Improve this question edited Nov 20, 2019 at 14:10 Dhanush Bala asked Nov 11, 2019 at 14:49 Dhanush BalaDhanush Bala 1,1321 gold badge14 silver badges28 bronze badges 2
  • Please provide some producible example, also you using hooks with classes which are not likely to pile. Refer to How to create a Minimal, Reproducible Example – Dennis Vash Commented Nov 11, 2019 at 15:04
  • I noticed you updated the question, you can check my new answer tell me if it helps. – Dennis Vash Commented Nov 21, 2019 at 19:30
Add a ment  | 

1 Answer 1

Reset to default 7 +50

Try changing innerRef to ref, you adding innerRef property and expecting it to be valid at 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;

Then you can access the ref as you like:

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>
  );
});

Edit:

For class ponents need to use another key then ref.

There is one caveat to the above example: refs will not get passed through. That’s because ref is not a prop. Like key, it’s handled differently by React. If you add a ref to a HOC, the ref will refer to the outermost container ponent, not the wrapped ponent.

// class ponent
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 ponent
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>
  );
}


Further, read:

  • Why, exactly, do we need React.forwardRef?

本文标签: javascriptpass forwardRef via cloneElement reactjsStack Overflow