反应功能组件继承

时间:2017-05-31 14:29:11

标签: reactjs functional-programming components code-reuse

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

我在内联网上工作,所以我会输入一个简单的例子......

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. 重复使用完全相同的组件,但检查一个道具中的数据,如果它存在循环并做其他方式循环通过另一个道具并做不同的事情
  3. 更改为使用React类而不是功能组件并使用继承(我以前没必要这样做,所以我必须做一些阅读)
  4. 更改为使用React类并使所有函数都是静态的,并使用两个组件中一个组件的静态函数。即。 aCellCreation()和bCellCreation()将是静态的。
  5. 我倾向于#2,但如果我想拥有基本相同的表并显示来自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;
    

1 个答案:

答案 0 :(得分:1)

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

我已经阅读了这些内容,在这些指导方针中,做了最好的事情。

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

相关问题