Reputation: 3529
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:
Upvotes: 2
Views: 2549
Reputation: 371193
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
}
}
Upvotes: 2