Reputation: 8759
I have two functions:
export default function Example() {
return (
<Widget>
<img src="/hello" />
</Widget>
)
}
export default function Widget() {
const ref = useRef(null)
return (
<div>
{children}
</div>
)
}
How do I apply 'ref' to the image element of Example
? Is there a way to always apply it to the first child element?
Upvotes: 0
Views: 179
Reputation: 387
You can use React's Context.
const MyContext = React.createContext();
function Widget(props) {
const myRef = useRef(null);
useEffect(() => {
myRef.current.focus();
});
return (
<MyContext.Provider value={myRef}>{props.children}</MyContext.Provider>
);
}
function Example() {
return (
<Widget>
<MyContext.Consumer>
{(forwardedRef) => <input type="text" ref={forwardedRef} />}
</MyContext.Consumer>
</Widget>
);
}
I created a demo for you: https://codesandbox.io/s/prod-voice-mkrcp
Upvotes: 0
Reputation: 1099
you can use cloneElement which helps us to clone and return a new React element using an element as the starting point. by this, we can add ref to element props, first, we made an array of childrens, then add our ref to the first one, e.g:
function Wrapper({ children }) {
const testRef = React.useRef(undefined);
const addReftoFirstChild = (chilrens, ref) => {
let elements = React.Children.toArray(chilrens);
return [React.cloneElement(elements[0], { ref })].concat(elements.slice(1));
};
return (
<>
{addReftoFirstChild(children, testRef)}
<button onClick={() => console.log(testRef.current)}>Test Ref!</button>
</>
);
}
function App() {
return (
<Wrapper>
<img
src='https://www.publicdomainpictures.net/pictures/80000/velka/odd-eyed-kitten.jpg'
width={200}
height={125}
/>
<img
src='https://c.files.bbci.co.uk/12A9B/production/_111434467_gettyimages-1143489763.jpg'
width={200}
height={125}
/>
</Wrapper>
);
}
Upvotes: 1