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

时间:2019-04-11 10:47:55

标签: javascript reactjs frontend react-hooks

我正在尝试将类组件重写为函数。

通常,我有一个增强的组件作为类属性:

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

表是一个外部组件(devexpressGrid),但我想它可以执行以下操作:

function Table(props) {
  const TableCell = props.tableCell
  return <TableCell param1={true} param2={true} />
}

有没有办法将道具从Grid传递到tableCell?这个道具不是来自任何redux存储,它是在渲染Grid时给出的,就像这样:

return <Grid paging="infinite-scroll" />

您可以在这里看到差异:

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

3 个答案:

答案 0 :(得分:1)

您可以内联创建一个新函数并将其直接提供给tableCell道具。

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} />;
}

答案 1 :(得分:1)

您可以在此处使用renderProps模式(我认为仍然可以使用它-但您可能更酷,可以考虑用Hooks替换它)

function Table(props) {
  return (
    <div>
     {props.render(props)}
    </div>
  )
}

实施:

function Grid(props) {
  return (
    <Table render={(props) => <TableCell {...props} />} />
  )
}

因此您的Table可以呈现任何组件并将其传递给所有或某些所需的道具。恕我直言,它使表格变得非常灵活。

答案 2 :(得分:0)

问题在于TabletableCell函数视为组件。如果有新功能,则重新安装层次结构。并且应该创建新函数以便使用props中的Grid,它不能像在类组件中那样工作,因为没有this.prop可以作为组件寿命期间的属性。

这是一个常见问题。 React Router通过拥有单独的component and render props来解决它。意外地将新创建的函数提供为component会导致非常相同的问题,一个组件将在每个渲染器上重新安装。

tableCell应该被视为常规函数,而不是组件。另一个答案提到,tableCell被称为render prop

Table组件应为:

function Table(props) {
  return props.tableCell({param1: true, param2: true});
}

不小心将组件提供为渲染道具可能会导致错误。遵循命名约定并以明确目的的方式称呼道具是个好习惯,例如renderCell用于渲染道具,CellcellComponent用于组件。