Based on the answer for the similar question, I have create the following example that includes the code you have provided in the question. Please note the definition differences between the cannotBeCalledFromParent
function and childFunctionCallableFromParent
or checkPercentage
function.
Parent component:
import ChildComponent from "./test-child";
import { useRef } from "react";
export default function ParentComponent() {
// In order to gain access to the child component instance,
// you need to assign it to a `ref`, so we call `useRef()` to get one
const childRef = useRef();
return (
<div>
<h1>Here is parent component</h1>
{/* sent the childRef to the child component as a value of the 'ref' property */ }
<ChildComponent ref={childRef} test='from parent through props' />
<button onClick={() => childRef.current.childFunctionCallableFromParent()}>Click</button>
</div>
);
}
Child component:
import { forwardRef, useImperativeHandle } from "react";
const ChildComponent = forwardRef((props, ref) => {
const cannotBeCalledFromParent = () => {
console.log("cannot be called from parent");
}
// The component instance will be extended
// with whatever you return from the callback passed
// as the second argument
useImperativeHandle(ref, () => {
return {
childFunctionCallableFromParent() {
// this function has access to all members of the child component
// for example 'props'
console.log("child function called: ", props.test);
// example on calling other functions from the component
cannotBeCalledFromParent();
this.checkPercentage();
},
// this function can also be called directly from parent
checkPercentage() {
let count = 0;
for(let list of lists){
if(list.title === "Done"){
setDoneId(list.listId);
}
}
for (let task of tasks) {
if (task.listId === doneId) {
count++;
setDoneCount(count);
}
setPercentDone((doneCount / tasks.length) * 100);
}
console.log("done count")
console.log(doneCount)
console.log(percentDone)
console.log(tasks)
}
}
});
return (
<div> I am child component </div>
)
});
export default ChildComponent;