React 函数式组件继承
Posted
技术标签:
【中文标题】React 函数式组件继承【英文标题】:React Functional Component Inheritance 【发布时间】:2017-11-01 10:05:50 【问题描述】:我创建了一个 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;
我认为做我想做的事的几种方法......
-
复制和粘贴不重复使用 - 不好
重用完全相同的组件,但检查一个道具中的数据,如果存在循环并以一种方式执行其他操作,则循环通过另一个道具并执行不同的操作
更改为使用 React 类而不是功能组件并使用继承(我以前不需要这样做,所以我必须做一些阅读)
更改为使用 React 类并让所有函数都是静态的,并在两个组件中使用来自一个组件的静态函数。 IE。 aCellCreation() 和 bCellCreation() 将是静态的。
我有点倾向于#2,但如果我想拥有基本相同的表格并显示来自 4 个不同来源的用户信息怎么办 - 它可能会变得丑陋。例如dataToMapThrough = props.allUsersData? props.allUserData : (props.usersFromUSAData? props.usersFromUSAData : ...)
对完成此任务的最佳方法有什么建议吗?
更新
如果有人感兴趣,我会在这里阅读 Andy_D 提供的文档。希望没有错别字,因为自从我在 Intranet 网站上工作以来,我不得不手动输入所有内容...
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】:React 文档在这里解决了这个问题:https://facebook.github.io/react/docs/composition-vs-inheritance.html
我已经阅读了该内容,并在这些指导方针的范围内,做任何看起来最好的事情。
TL;DR - 不要使用继承。但请务必阅读。
【讨论】:
以上是关于React 函数式组件继承的主要内容,如果未能解决你的问题,请参考以下文章