I have a component A that receives a component B as argument and renders it.
I'd like the component B - which I receive in component A as an argument - to call a function in component A.
So I would have to pass an attribute to component B, but I can't because I render it as an argument:
<ComponentABody>
{ComponentB}
</ComponentABody>
What I'd like to do could be exemplified as:
<ComponentABody>
{ComponentB attribute={componentAFunction} }
</ComponentABody>
CodePudding user response:
Please do not use cloneElement or any sort of hack. Use the React Context API, it is what it is designed for.
Component A will render a context provider, with the function [you want component B to execute] passed down as a context value
Component B will read the context value, take the function [passed by Component A] from it, and call it when needed
Example:
// ---------------
// --- Context ---
// ---------------
type ComponentAContextValue = {
myFunction
}
const ComponentAContext = React.createContext<
ComponentAContextValue | null
>(null);
// -------------------
// --- Component A ---
// -------------------
const ComponentA = ({ children }) => {
const someFunction = () => {}
const contextValue = React.useMemo(() => ({
myFunction: someFunction
}))
return (
<ComponentAContext.Provider value={contextValue}>
{children}
</ComponentAContext.Provider>
)
}
// -------------------
// --- Component B ---
// -------------------
const ComponentB = ({ children }) => {
const contextValue = React.useContext(ComponentAContext);
const handleEvent = () => {
contextValue?.myFunction()
}
return (
<div>{children}</div>
);
}
// -------------------
// --- Usages --------
// -------------------
// valid usage
const componentB = <ComponentB>foo</ComponentB>
<ComponentA>{componentB}</ComponentA>
// also valid usage
<ComponentA>
<ComponentB>
Foo
</ComponentB>
</ComponentA>
CodePudding user response:
<ComponentABody>
<ComponentB attribute={componentAFunction} />
</ComponentABody>
you can write it this way, if you want componentB in componentA, and pass its attributes.
To access component, use props.children