I am trying to rewrite class components to functions.
Often, I have an enhanced component as class property:
class Grid extends Component { tableCell = params => ( <TableCell paging={this.props.paging} {...params} /> ) render() { return <Table tableCell={this.tableCell} /> } }
When writing function, I have to move the enhancing outside of function body, or it will get re-mounted on each render.
const tableCell = params => <TableCell {...params} /> function Grid(props) { return <Table tableCell={tableCell} /> }
Table is an external Component (devexpressGrid), but I suppose it does something like this:
function Table(props) { const TableCell = props.tableCell return <TableCell param1={true} param2={true} /> }
Is there a way, to still pass a prop from Grid to tableCell? This prop is not coming from any redux store, it is given when rendering Grid, like this:
return <Grid paging="infinite-scroll" />
You can see the differences here:
https://codesandbox.io/s/w2y76w53ww?fontsize=14
Advertisement
Answer
The problem is that Table
treats tableCell
function as a component. If there’s new function, the hierarchy is remounted. And new function is supposed to be created in order to use props
from Grid
, it cannot work the same way as it does in class component because there’s no this.prop
that could be accessed as a property during component lifespan.
This is a common problem. React Router solves it by having separate component
and render
props. Accidentally providing newly created function as component
will result in very same problem, a component will be remounted on each render.
tableCell
should be treated as regular function rather than a component. As another answer mentions, tableCell
is called render prop.
Table
component should be:
function Table(props) { return props.tableCell({param1: true, param2: true}); }
Accidentally providing a component as render prop may result in error. It’s a good practice to follow naming convention and call a prop the way its purpose is clear, e.g. renderCell
for render prop and Cell
or cellComponent
for a component.