从 类 重构为函数 - 增强函数的方法
Refactoring from classes to functions - ways to enhance in functions
我正在尝试将 class 个组件重写为函数。
通常,我有一个增强组件 class 属性:
class Grid extends Component {
tableCell = params => (
<TableCell paging={this.props.paging} {...params} />
)
render() {
return <Table tableCell={this.tableCell} />
}
}
在编写函数时,我必须将增强功能移到函数体之外,否则它会在每次渲染时重新安装。
const tableCell = params => <TableCell {...params} />
function Grid(props) {
return <Table tableCell={tableCell} />
}
Table 是一个外部组件 (devexpressGrid),但我想它会做这样的事情:
function Table(props) {
const TableCell = props.tableCell
return <TableCell param1={true} param2={true} />
}
有没有办法仍然将 prop 从 Grid 传递到 tableCell?这个 prop 不是来自任何 redux store,它是在渲染 Grid 时给出的,像这样:
return <Grid paging="infinite-scroll" />
您可以在此处查看差异:
您可以创建一个新的内联函数并将其直接提供给 tableCell
prop。
function Grid(props) {
return (
<Table tableCell={params => <TableCell paging={paging} {...params} />} />
)
}
如果您不想在每次渲染时都创建一个新函数,您可以使用 useCallback
挂钩。
function Grid(props) {
const tableCell = useCallback(
params => <TableCell paging={paging} {...params} />,
[paging]
);
return <Table tableCell={tableCell} />;
}
你可以在这里使用 renderProps 模式(我认为它仍然可以使用它 - 但你可能会更酷并考虑用 Hooks 替换它)
function Table(props) {
return (
<div>
{props.render(props)}
</div>
)
}
实施:
function Grid(props) {
return (
<Table render={(props) => <TableCell {...props} />} />
)
}
因此您的 Table 可以渲染任何组件并传递它的全部或部分所需道具。恕我直言,它使 Table 非常灵活。
问题在于 Table
将 tableCell
函数视为组件。如果有新功能,则重新安装层次结构。并且应该创建新函数以便使用 Grid
中的 props
,它不能像在 class 组件中那样工作,因为没有 this.prop
可以在组件生命周期内作为 属性 访问。
这是一个常见问题。 React Router 通过单独 component
and render
props 来解决它。不小心将新创建的函数提供为 component
将导致非常相同的问题,将在每个渲染器上重新安装一个组件。
tableCell
应被视为常规函数而不是组件。正如另一个答案提到的,tableCell
被称为 render prop。
Table
组件应为:
function Table(props) {
return props.tableCell({param1: true, param2: true});
}
不小心将组件提供为 render prop 可能会导致错误。遵循命名约定并以其目的明确的方式调用道具是一种很好的做法,例如renderCell
用于渲染道具,Cell
或 cellComponent
用于组件。
我正在尝试将 class 个组件重写为函数。
通常,我有一个增强组件 class 属性:
class Grid extends Component {
tableCell = params => (
<TableCell paging={this.props.paging} {...params} />
)
render() {
return <Table tableCell={this.tableCell} />
}
}
在编写函数时,我必须将增强功能移到函数体之外,否则它会在每次渲染时重新安装。
const tableCell = params => <TableCell {...params} />
function Grid(props) {
return <Table tableCell={tableCell} />
}
Table 是一个外部组件 (devexpressGrid),但我想它会做这样的事情:
function Table(props) {
const TableCell = props.tableCell
return <TableCell param1={true} param2={true} />
}
有没有办法仍然将 prop 从 Grid 传递到 tableCell?这个 prop 不是来自任何 redux store,它是在渲染 Grid 时给出的,像这样:
return <Grid paging="infinite-scroll" />
您可以在此处查看差异:
您可以创建一个新的内联函数并将其直接提供给 tableCell
prop。
function Grid(props) {
return (
<Table tableCell={params => <TableCell paging={paging} {...params} />} />
)
}
如果您不想在每次渲染时都创建一个新函数,您可以使用 useCallback
挂钩。
function Grid(props) {
const tableCell = useCallback(
params => <TableCell paging={paging} {...params} />,
[paging]
);
return <Table tableCell={tableCell} />;
}
你可以在这里使用 renderProps 模式(我认为它仍然可以使用它 - 但你可能会更酷并考虑用 Hooks 替换它)
function Table(props) {
return (
<div>
{props.render(props)}
</div>
)
}
实施:
function Grid(props) {
return (
<Table render={(props) => <TableCell {...props} />} />
)
}
因此您的 Table 可以渲染任何组件并传递它的全部或部分所需道具。恕我直言,它使 Table 非常灵活。
问题在于 Table
将 tableCell
函数视为组件。如果有新功能,则重新安装层次结构。并且应该创建新函数以便使用 Grid
中的 props
,它不能像在 class 组件中那样工作,因为没有 this.prop
可以在组件生命周期内作为 属性 访问。
这是一个常见问题。 React Router 通过单独 component
and render
props 来解决它。不小心将新创建的函数提供为 component
将导致非常相同的问题,将在每个渲染器上重新安装一个组件。
tableCell
应被视为常规函数而不是组件。正如另一个答案提到的,tableCell
被称为 render prop。
Table
组件应为:
function Table(props) {
return props.tableCell({param1: true, param2: true});
}
不小心将组件提供为 render prop 可能会导致错误。遵循命名约定并以其目的明确的方式调用道具是一种很好的做法,例如renderCell
用于渲染道具,Cell
或 cellComponent
用于组件。