React 功能组件继承

React Functional Component Inheritance

我创建了一个 React 功能组件,它是 react-data-grid 组件的包装器。现在我需要第二个完全相同的组件,除了一个功能(如果您熟悉 react-data-grid,则为 rowGetter。)

我在 Intranet 上工作,所以我将输入一个简单的示例...

function UsersInfoDataTable(props) {

  const userInfoCols = [
    {key: "a", name: "A", ...},
    {key: "b", name" "B", ...},
    {key: "c", name" "C", ...},
    ...
  ];

  const aCellCreation = (aData, description, index) => (
    <span title={...}>...</span>
  )

  const bCellCreation = (bData, index) => (
    <div className={...}>...</div>
  }

  ...

  
  const formattedTableData = props.myData.map(function (obj, index) {
    //do some stuff
    return {"a": aCellCreation(obj.a, obj.desc,index), "b": bCellCreation(obj.b, index), ...}
  });

  const rowGetter = rowNumber => formattedTableData[rowNumber];

  return (
    <div>
      <ReactDataGrid
        columns={userInfoCols}
        rowGetter={rowGetter}
        rowCount={formattedTableData.length}
        minHeight={props.minHeight}
       />
     </div>
   )
}

export default UsersInfoDataTable;

现在我也需要这样的东西...

function UsersInfoDataTableSlightlyDifferent(props) {

  //i need the same columns
  const userInfoCols = [
    {key: "a", name: "A", ...},
    {key: "b", name: "B", ...}
  ];

  //i need same cell format    
  const aCellCreation = (aData, description, index) => (
    <span title={...}>...</span>
  )

  //i need same cell format
  const bCellCreation = (bData, index) => (
    <div className={...}>...</div>
  }

  ...

  //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 "creation" functions
    return {"a": aCellCreation(obj.a, obj.desc,index), "b": bCellCreation(obj.b, index), ...}
  });

  const rowGetter = rowNumber => formattedTableData[rowNumber];

  return (
    <div>
      <ReactDataGrid
        columns={userInfoCols}
        rowGetter={rowGetter}
        rowCount={formattedTableData.length}
        minHeight={500}
       />
     </div>
   )
}

export default UsersInfoDataTable;

我想做我想做的几种方法...

  1. 无法重复使用的复制和粘贴 - 不好
  2. 重复使用完全相同的组件,但检查一个 prop 中的数据,如果它存在,循环并以一种方式做事,否则循环通过另一个 prop 并做不同的事
  3. 更改为使用 React class 而不是功能组件并使用继承(我以前不必这样做,所以我必须做一些阅读)
  4. 更改为使用 React class 并使所有函数都是静态的,并在两个组件中使用来自一个组件的静态函数。 IE。 aCellCreation() 和 bCellCreation() 将是静态的。

我有点倾向于#2,但如果我想拥有基本相同的 table 并显示来自 4 个不同来源的用户信息怎么办 - 它可能会变得丑陋。例如dataToMapThrough = props.allUsersData? props.allUserData : (props.usersFromUSAData? props.usersFromUSAData : ...)

关于完成此任务的最佳方法有什么建议吗?


更新

阅读 Andy_D 提供的文档,如果有人感兴趣的话,这是我想出的。希望没有错别字,因为我在内部网站上工作,所以我不得不手动输入所有内容...

function UsersInfoDataTableDisplayer(props) {

  const userInfoCols = [
    {key: "a", name: "A", ...},
    {key: "b", name: "B", ...}
  ];

  const aCellCreation = (aData, description, index) => (
    <span title={...}>...</span>
  )

  const bCellCreation = (bData, index) => (
    <div className={...}>...</div>
  }

  ...

  //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 {"a": aCellCreation(obj.a, obj.b,index), "b": bCellCreation(obj.b, index),"c": obj.c}
  });

  const rowGetter = rowNumber => formattedTableData[rowNumber];

  return (
    <div>
      <ReactDataGrid
        columns={userInfoCols}
        rowGetter={rowGetter}
        rowCount={formattedTableData.length}
        minHeight={500}
       />
     </div>
   )
}

export default UsersInfoDataTableDisplayer;

现在这是一个专门的版本 #1...

function UsersInfoFromService1DataTable(props) {

  //The format of the JSON passed in is one way here 
  const formattedTableData = props.abcData.map(function (obj, index) {

    //"combine" and "clean" or whatever you need here
    let aLikeData = obj.firstName + ' ' + obj.lastName

    return {"a": aLikeData, "b": obj.description, "c": obj.whatever,...}
  });



  return (
    <div>
      <UsersInfoDataTableDisplayer
        userInfoData = {formattedTableData}
        minHeight={500}
       />
     </div>
   )
}

export default UsersInfoFromService1DataTable;

这是专业版本 #2...

function UsersInfoFromService1DataTable(props) {

  //The format of the JSON passed in is one way here 
  const formattedTableData = props.xyzData.map(function (obj, index) {

    //"combine" and "clean" or whatever you need here
    let aLikeData = obj.fullName

    return {"a": aLikeData, "b": obj.desc, "c": obj.something,...}
  });



  return (
    <div>
      <UsersInfoDataTableDisplayer
        userInfoData = {formattedTableData}
        minHeight={900}
       />
     </div>
   )
}

export default UsersInfoFromService2DataTable;

React 文档在这里解决了这个问题:https://facebook.github.io/react/docs/composition-vs-inheritance.html

我已经阅读了该指南,并在这些指导方针的范围内尽我所能。

TL;DR - 不要使用继承。但请务必阅读。