Reputation: 99
Scenario 1: Works fine
This is the ParentComponent
import React, { Children } from 'react'
import ChildComponent from './ChildComponent';
const ParentComponent = () => {
const buttonRef = React.useRef({ focusHandler: () => alert("hi") });
return (
<div>
<ChildComponent ref={buttonRef} />
</div>
);
};
export default ParentComponent;
This is the Child Component using Forward Reference.
import React from 'react'
const ChildComponent = React.forwardRef((props, ref) => {
return (
<div>
<button onClick={ref.current.focusHandler}>Focus Input</button>
</div>
);
});
export default ChildComponent;
Scenario 2: Need help here
Now, what if, the ParentComponent doesn't ChildComponent and I wish to call the ChildComponent like so in the main page:
MainPage.js:
import React from 'react'
import ParentComponentScenario2 from './ParentComponentScenario2';
import ChildComponentScenario2 from './ChildComponentScenario2';
const MainPage = () => {
return (
<div>
<ParentComponentScenario2>
<ChildComponentScenario2 />
</ParentComponentScenario2>
</div>
)
}
export default MainPage;
ParentComponentScenario2:
import React, { Children } from 'react'
const ParentComponentScenario2 = () => {
const buttonRef = React.useRef({ focusHandler: () => alert("hi") });
return (
<div>
{props.children};
</div>
);
};
export default ParentComponentScenario2;
Query, how do I pass the method in ChildComponent now as <ChildComponent ref={buttonRef} />
isn't possible now on the page.
ChildComponentScenario2:
import React from 'react'
//How to implement onClick, props.focusHandler doesn't seem to work for some reason either.
const ChildComponentScenario2 = () => {
return (
<div>
<button onClick={props.focusHandler}>Focus Input</button>
</div>
)
}
export default ChildComponentScenario2;
Upvotes: 0
Views: 131
Reputation: 53884
You need to "inject" properties using React.Children
API and React.cloneElement
:
const ParentComponent = ({ children }) => {
const buttonRef = React.useRef({ focusHandler: () => console.log("ref") });
const focusHandler = () => console.log("callback");
return (
<div>
{React.Children.map(children, child =>
React.cloneElement(child, { ref: buttonRef, focusHandler })
)}
</div>
);
};
const ChildComponent = React.forwardRef(({ focusHandler }, ref) => {
return (
<div>
<button onClick={ref?.current.focusHandler}>Ref</button>
<button onClick={focusHandler}>Callback</button>
</div>
);
});
Upvotes: 1