title: React Functional Component Inheritance
body: <p>i created a React functional component that is a wrapper around the react-data-grid component. now i need a second component that is exactly the same except for one function (the rowGetter if you are familiar with react-data-grid.)</p>
  <p>i work on an intranet so i will type a quick example...</p>
  <pre><code>function UsersInfoDataTable(props) {
  
    const userInfoCols = [
      {key: &quot;a&quot;, name: &quot;A&quot;, ...},
      {key: &quot;b&quot;, name&quot; &quot;B&quot;, ...},
      {key: &quot;c&quot;, name&quot; &quot;C&quot;, ...},
      ...
    ];
  
    const aCellCreation = (aData, description, index) =&gt; (
      &lt;span title={...}&gt;...&lt;/span&gt;
    )
  
    const bCellCreation = (bData, index) =&gt; (
      &lt;div className={...}&gt;...&lt;/div&gt;
    }
  
    ...
  
    
    const formattedTableData = props.myData.map(function (obj, index) {
      //do some stuff
      return {&quot;a&quot;: aCellCreation(obj.a, obj.desc,index), &quot;b&quot;: bCellCreation(obj.b, index), ...}
    });
  
    const rowGetter = rowNumber =&gt; formattedTableData[rowNumber];
  
    return (
      &lt;div&gt;
        &lt;ReactDataGrid
          columns={userInfoCols}
          rowGetter={rowGetter}
          rowCount={formattedTableData.length}
          minHeight={props.minHeight}
         /&gt;
       &lt;/div&gt;
     )
  }
  
  export default UsersInfoDataTable;
  </code></pre>
  <p>now i need something like this too...</p>
  <pre><code>function UsersInfoDataTableSlightlyDifferent(props) {
  
    //i need the same columns
    const userInfoCols = [
      {key: &quot;a&quot;, name: &quot;A&quot;, ...},
      {key: &quot;b&quot;, name: &quot;B&quot;, ...}
    ];
  
    //i need same cell format    
    const aCellCreation = (aData, description, index) =&gt; (
      &lt;span title={...}&gt;...&lt;/span&gt;
    )
  
    //i need same cell format
    const bCellCreation = (bData, index) =&gt; (
      &lt;div className={...}&gt;...&lt;/div&gt;
    }
  
    ...
  
    //the internals of this function will be pretty much the only difference
    const formattedTableData = props.myData.map(function (obj, index) {
  
      //do some different stuff than previous component as myData will be
      //in a different format when passed here versus the other component
  
      //the return will be essentially the same - maybe slightly different with
      //what is passed to the &quot;creation&quot; functions
      return {&quot;a&quot;: aCellCreation(obj.a, obj.desc,index), &quot;b&quot;: bCellCreation(obj.b, index), ...}
    });
  
    const rowGetter = rowNumber =&gt; formattedTableData[rowNumber];
  
    return (
      &lt;div&gt;
        &lt;ReactDataGrid
          columns={userInfoCols}
          rowGetter={rowGetter}
          rowCount={formattedTableData.length}
          minHeight={500}
         /&gt;
       &lt;/div&gt;
     )
  }
  
  export default UsersInfoDataTable;
  </code></pre>
  <p>A couple ways i thought to do what i want...</p>
  <ol>
  <li>Copy and paste with no reuse - bad</li>
  <li>Reuse the exact same component but check for data in one prop and if it exists loop and do stuff one way else loop through the other prop and do stuff different</li>
  <li>Change to use a React class instead of functional component and use inheritance (which i haven't had to do before so i'd have to do some reading)</li>
  <li>Change to use a React class and have all the functions be static and use them the static functions from one component in both components. ie. aCellCreation() and bCellCreation() would be static.</li>
  </ol>
  <p>i'm kind of leaning towards #2 but what if i want to have essentially the same table and display user info from 4 different sources - it could get ugly. e.g. <code>dataToMapThrough = props.allUsersData? props.allUserData : (props.usersFromUSAData? props.usersFromUSAData : ...)</code></p>
  <p>Any suggestions on the best way to accomplish this?</p>
  <hr />
  <h2>UPDATE</h2>
  <p>Reading the document provided by Andy_D here is what i came up with if anyone is interested.  Hopefully no typos since i had to hand type everything since i work on an intranet site...</p>
  <pre><code>function UsersInfoDataTableDisplayer(props) {
  
    const userInfoCols = [
      {key: &quot;a&quot;, name: &quot;A&quot;, ...},
      {key: &quot;b&quot;, name: &quot;B&quot;, ...}
    ];
  
    const aCellCreation = (aData, description, index) =&gt; (
      &lt;span title={...}&gt;...&lt;/span&gt;
    )
  
    const bCellCreation = (bData, index) =&gt; (
      &lt;div className={...}&gt;...&lt;/div&gt;
    }
  
    ...
  
    //data will already be processed exactly how this Component needs it every time
    //in the specialized version of this Component
    const formattedTableData = props.userInfoData.map(function (obj, index) {
  
      //Probably nothing to do here since data is processed in the specialized 
      //version of this component
  
      return {&quot;a&quot;: aCellCreation(obj.a, obj.b,index), &quot;b&quot;: bCellCreation(obj.b, index),&quot;c&quot;: obj.c}
    });
  
    const rowGetter = rowNumber =&gt; formattedTableData[rowNumber];
  
    return (
      &lt;div&gt;
        &lt;ReactDataGrid
          columns={userInfoCols}
          rowGetter={rowGetter}
          rowCount={formattedTableData.length}
          minHeight={500}
         /&gt;
       &lt;/div&gt;
     )
  }
  
  export default UsersInfoDataTableDisplayer;
  </code></pre>
  <p>Now here is a specialized version #1...</p>
  <pre><code>function UsersInfoFromService1DataTable(props) {
  
    //The format of the JSON passed in is one way here 
    const formattedTableData = props.abcData.map(function (obj, index) {
  
      //&quot;combine&quot; and &quot;clean&quot; or whatever you need here
      let aLikeData = obj.firstName + ' ' + obj.lastName
  
      return {&quot;a&quot;: aLikeData, &quot;b&quot;: obj.description, &quot;c&quot;: obj.whatever,...}
    });
  
  
  
    return (
      &lt;div&gt;
        &lt;UsersInfoDataTableDisplayer
          userInfoData = {formattedTableData}
          minHeight={500}
         /&gt;
       &lt;/div&gt;
     )
  }
  
  export default UsersInfoFromService1DataTable;
  </code></pre>
  <p>Here is specialized version #2...</p>
  <pre><code>function UsersInfoFromService1DataTable(props) {
  
    //The format of the JSON passed in is one way here 
    const formattedTableData = props.xyzData.map(function (obj, index) {
  
      //&quot;combine&quot; and &quot;clean&quot; or whatever you need here
      let aLikeData = obj.fullName
  
      return {&quot;a&quot;: aLikeData, &quot;b&quot;: obj.desc, &quot;c&quot;: obj.something,...}
    });
  
  
  
    return (
      &lt;div&gt;
        &lt;UsersInfoDataTableDisplayer
          userInfoData = {formattedTableData}
          minHeight={900}
         /&gt;
       &lt;/div&gt;
     )
  }
  
  export default UsersInfoFromService2DataTable;
  </code></pre>