从 类 重构为函数 - 增强函数的方法

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" />

您可以在此处查看差异:

https://codesandbox.io/s/w2y76w53ww?fontsize=14

您可以创建一个新的内联函数并将其直接提供给 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 非常灵活。

问题在于 TabletableCell 函数视为组件。如果有新功能,则重新安装层次结构。并且应该创建新函数以便使用 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 用于渲染道具,CellcellComponent 用于组件。