How to loop through refs in React and get values?

Viewed 1649

How can I loop through paragraphs in Child component and get its innerHTML value in Parent component? I have to do this with refs.

class Parent extends React.Component {
  render() {
    return (
      <Child
        textRef={el => this.textElement = el}
      />
    );
  }
}

function Child(props) {
  return (
    <div>
      <p ref={props.textRef} >abc</p>
      <p ref={props.textRef} >def</p>
      <p ref={props.textRef} >ghi</p>
    </div>
  );
}
2 Answers

I've used an array to store those ref. You can check this.

function Parent() {
  const textElements = [];

  React.useEffect(() => {
    textElements.forEach(el => console.log(el))
  }, [textElements]);

  return <Child textRef={el => textElements.push(el)} />;
}

function Child(props) {
  return (
    <div>
      <p ref={props.textRef}>abc</p>
      <p ref={props.textRef}>def</p>
      <p ref={props.textRef}>ghi</p>
    </div>
  );
}





const rootElement = document.getElementById("root");
ReactDOM.render(<Parent/>, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.1/umd/react-dom.production.min.js"></script>  
<div id="root"></div>

You need to maintain an array of refs, and also you should update the passed reference from the parent component.

For class component use React.createRef instead, and componentDidMount for useEffect.

I think this example explains itself.

/* Logs: ["abc", "def", "ghi"] */

const Parent = () => {
  const textRef = useRef();

  useEffect(() => {
    console.log(textRef.current.map(ref => ref.innerHTML));
  }, []);

  return <Child innerRef={textRef} />;
};

const Child = ({ innerRef }) => {
  const pRefs = useRef([]);

  useEffect(() => {
    innerRef.current = pRefs.current;
  }, [innerRef]);

  return (
    <div>
      <p ref={ref => (pRefs.current[0] = ref)}>abc</p>
      <p ref={ref => (pRefs.current[1] = ref)}>def</p>
      <p ref={ref => (pRefs.current[2] = ref)}>ghi</p>
    </div>
  );
};

If you need to loop for an unknown number of p elements, use React.Children API.

Edit dank-feather-cs0zr

Related