How to call Parent containers function from child component in Reactjs

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;

2 answers

  • answered 2022-01-13 05:08 Ramesh Reddy

    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>
      );
    }
    

    Edit hardcore-ully-risj5


    If your app already uses redux, then you can move arrangeTiles to the reducer and dispatch actions from the components.

  • answered 2022-01-13 06:18 Jevon Cochran

    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);
    

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum