Good day. I have three components. A Master Component, A TopBar and a Child component (Refers to the rest of my application). The Master is a layout wrapper that nests the Child Component. The Top Bar component is used inside the Master Component so that it is constant througout the site. The Challenge is that, when a button is clicked on the Top Bar, I want a function to be called inside the Child Component.
What is the best possible way to achieve this
Master.js
import React from 'react'
import TopBar from './TopBar'
const Master = (props) => {
function handleFunc (childFunc) {
setChildFunction(childFunc);
}
return (
<>
<div>
<TopBar onHandle={handleFunc}/>
{props.children}
</div>
</>
)
}
export default Master
TopBar.js
import React from 'react'
const TopBar = ({onHandle}) => {
const childFunc = React.useRef(null)
function handleClick (){
childFunc.current();
onHandle(childFunc);
}
return (
<div>
<button onClick={() => handleClick()}>Click on Me</button> {/* Triggers the alert() function in Child.js */}
</div>
)
}
export default TopBar
Child.js
import React from 'react'
import Master from './Master'
const Child = () => {
function alert(){
console.log("This function is called when thew Top Bar Button is clicked");
}
return (
<div>
<Master>
Child Contents
</Master>
</div>
)
}
export default Child
What is the best way to achieve this. I initially wanted to pass the ref object to the Master component so it can be passed down to the Child as shown above, but I keep getting errors (that "childFunc" is not a function).
Thanks in advance
CodePudding user response:
You should pass the alert
function as parameter to the Master
component:
<Master alert={alert}>...</>
And then pass it to the TopBar
:
<TopBar onHandle={props.alert}/>
And handle the click event in TopBar
with:
const TopBar = ({ onHandle }) => {
...
return (
<div>
<button onClick={onHandle}>
</div>
)
}
CodePudding user response:
You can pass your Child function to the Master component, then from the Master Component to TopBar component, that will cause props drilling but it will solve your problem, Child.js
import React from 'react'
import Master from './Master'
const Child = () => {
function alert(){
console.log("This function is called when thew Top Bar Button is clicked");
}
return (
<div>
<Master func={alert}>
Child Contents
</Master>
</div>
)
}
export default Child
Master.js
import TopBar from './TopBar'
const Master = ({func}) => {
return (
<>
<div>
<TopBar func={func}/>
{props.children}
</div>
</>
)
}
export default Master
TopBar.js
import React from 'react'
const TopBar = ({func}) => {
return (
<div>
<button onClick={() => func()}>Click on Me</button>
</div>
)
}
export default TopBar