Reputation: 133
My application renders dynamic tiles by user and the tiles need to be re-arranged based on external configuration, StyleWrapper need to be a common container component that can be used in other projects too. Following is our UI component structure:
<StyleWrapper>
<Header />
<Content>
<PortletTiles />
</Content>
</StyleWrapper>
Given above structure, I have a function in StyleWrapper.tsx called arrangeTiles() which arranges tiles based on external configuration.
My question is how to call arrangeTiles() function from child component PortletTiles.tsx
StyleWrapper.tsx --> Parent Wrapper Container component
function StyleWrapper(props:any) {
let arrangeTiles= () => {
// Arrange Tile logic
};
return (
<div id="cnplStyleWrapper">
{props.children}
</div>
);
}
export default StyleWrapper;
PortletTiles.tsx --> Child component
function PortletTiles(props:any) {
let addNewTile= () => {
// Some logic to render tile here.. then
// How to call parent container's arrangeTiles function?
};
return (
<div>
<button onClick={addNewTile}>Add Tile</button>
</div>
);
}
export default PortletTiles;
Upvotes: 1
Views: 281
Reputation: 1774
The easiest way to go about this would be to use context API. This provides you with the ability to have state that you can reference and manipulate across different components. You can reference the docs for context API here.
import { createContext } from "react";
const AppContext = createContext();
const AppProvider = (props) => {
const arrangeTiles = () => {
// place function code here
};
return (
<AppContext.Provider value={{arrangetiles}}>
{props.children}
</SiteContext.Provider>
);
};
const AppConsumer = AppContext.Consumer;
export { AppContext, AppConsumer };
export default AppProvider;
Wrap your app component in the AppProvider
In the child component, you would need to import the rearrangeTiles function and then you can use it:
import { useContext } from "react";
const { rearrangeTiles } = useContext(AppContext);
Upvotes: 0
Reputation: 10662
You can create a context
and pass the function or any other props as value
. useContext
can be used to consume the passed value
from the provider.
type ContextValue = {
arrangeTiles: () => void;
};
const Context = createContext<ContextValue>({
arrangeTiles: () => {}
});
const StyleWrapper: FC = (props) => {
let arrangeTiles = () => {
// Arrange Tile logic
alert("Tiles have been arranged!");
};
return (
<Context.Provider value={{ arrangeTiles }}>
<div id="cnplStyleWrapper">{props.children}</div>
</Context.Provider>
);
};
const PortletTiles: FC = (props) => {
const { arrangeTiles } = useContext(Context);
let addNewTile = () => {
arrangeTiles();
};
return (
<div>
<button onClick={addNewTile}>Add Tile</button>
</div>
);
};
export default function App() {
return (
<StyleWrapper>
<PortletTiles />
</StyleWrapper>
);
}
If your app already uses redux, then you can move arrangeTiles
to the reducer and dispatch actions from the components.
Upvotes: 1