Home > Net >  How can I use multiple refs for nested arrays of elements with hooks, or any other way
How can I use multiple refs for nested arrays of elements with hooks, or any other way

Time:06-12

First of all, I've found the solution here, which works great with a single array of elements. But my question is regarding the nested arrays of components. For example:

const { useRef, useState, useEffect } = React;

const arr1 = [A, B, C]
const arr2 = [1, 2, 3]

const App = () => {
  const popoverRefs = useRef([]);

  return (
    <div>
      {arr1.map((parentItem, index) => {
        return(
          <div>
            A Parent Element {parentItem.label}
            {arr2.map((childItem, index2) => {
              return (
                <div ref={????}>
                  A Child Element {childItem.label}     
                </div>
              )
             })}
          </div>
        )
      })}
    </div>
  );
};

ReactDOM.render(
  <App />,
  document.getElementById("root")
);

In this example how can I use useRef or createRef to get the reference for each parent's child separately, so that I can use those references to anchor some other view for example a popover.

CodePudding user response:

There are many other ways I manage same case using object

popoverRefs.current will look like
{
  0: [],
  1: [],
  2: [],
};

const {useRef, useState, useEffect} = React;

const arr1 = [A, B, C];
const arr2 = [1, 2, 3];

const App = () => {
  const popoverRefs = useRef(
    arr1.reduce((result, current, currentIndex) => {
      result[current] = [];
      return result;
    }, {}),
  );

  return (
    <div>
      {arr1.map((parentItem, index) => {
        return (
          <div>
            A Parent Element {parentItem.label}
            {arr2.map((childItem, index2) => {
              return (
                <div ref={ref => (popoverRefs.current[index][index2] = ref)}>
                  A Child Element {childItem.label}
                </div>
              );
            })}
          </div>
        );
      })}
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById('root'));

CodePudding user response:

You can extract the child into a separate component and create the ref there.

const { useRef, useState } = React;

const arr1 = ["A", "B", "C"];
const arr2 = [1, 2, 3];

const Child = ({ childItem }) => {
  const liRef = useRef();
  const handleClick = () => {
    liRef.current.classList.toggle("highlight");
  };
  return (
    <div ref={liRef}>
      A Child Element {childItem}{" "}
      <button onClick={handleClick}>Highlight</button>
    </div>
  );
};

const App = () => {
  return (
    <div>
      {arr1.map((parentItem, index) => {
        return (
          <div key={index}>
            <strong>A Parent Element {parentItem}</strong>
            {arr2.map((childItem, index2) => {
              return <Child childItem={childItem} key={index2}></Child>;
            })}
          </div>
        );
      })}
    </div>
  );
};

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
.highlight {
  background: yellow;
  color: red;
}
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div id="root"></div>

  • Related