2

I have a custom component with multiple sub components like this:

interface MyComponentProps {
  ref: any; 
}; 

function MyComponent(props: MyComponentProps){
  return <>
  <input id="name" type="number" />
  <input id="age" type="text" />
  </>
}

I'd like props.ref to contain values of all subcomponents, when accessed from the outside. Example: myref.current?.value.name and myref.current?.value.age should be possible. How do I do that?

Constraints:

  • Why am I searching for a ref-solution?
    • I'd like to keep the interface of the component as native-felt as possible.
1

1 Answer 1

2

You can create a ref for each other component, then combine those into a single ref.

const App = () => {
    const ref = React.useRef();
    setInterval(() => {
      console.log(ref.current.nameRef.current.value);
      console.log(ref.current.ageRef.current.value);
    }, 1000);
    return <MyComponent combinedRef={ref} />;
};
function MyComponent(props){
  const nameRef = React.useRef();
  const ageRef = React.useRef();
  React.useEffect(() => {
    props.combinedRef.current = { nameRef, ageRef };
  }, []);
  return <div>
    <input id="name" type="number" ref={nameRef} />
    <input id="age" type="text" ref={ageRef} />
  </div>;
}

ReactDOM.createRoot(document.querySelector('.react')).render(<App />);
<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 class='react'></div>

That said, this is a very odd pattern to want to have in React - it doesn't go well at all with how React control flow should usually be, I wouldn't recommend it.

If you must use the exact path myref.current?.value.name, you'll need to make both inputs controlled components, and then inside MyComponent, do:

props.combinedRef.current = {
  value: { // should there really be an extra level of nesting here?
    name,
    age
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

very helpful. I tweaked it to props.combinedRef.current = { name: nameRef.current?.value, age: ageRef.current?.value, };

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.