Reputation: 865
I'm using TypeScript with React and Semantic-UI-React. I'd like to replace an existing table rendering which renders table cells using intrinsic 'td' elements, like this:
<td className={cssClass} key={idx} onClick={handleClick}>{txt}</td>
with one that uses Semantic-UI.React Table.Cell elements, like this:
<Table.Cell className={cssClass} key={idx} onClick={handleClick}>{txt}</Table.Cell>
The problem is that the property 'onClick' doesn't exist on the strongly typed 'Table.Cell' element (whose props are determined by the TableCellProps interface) and so the code can't be compiled.
My workaround is to compose the Table.Cell element in an element whose props sub-class TableCellProps like this:
interface MyTableCellProps extends TableCellProps {
onClick?: React.EventHandler<React.MouseEvent<any>>;
}
const MyTableCell: React.SFC<MyTableCellProps> = (props) => <Table.Cell {...props} />;
and then render a cell as:
<MyTableCell className={cssClass} key={idx} onClick={handleClick}>{txt}</MyTableCell>
But this results in a more deeply nested React structure (although the final HTML rendering looks OK).
My questions is: Is there a more idiomatic way of doing this with Semantic-UI-React when using TypeScript?
A hint that there ought to be a way is given in the Semantic-ui-react documentation in the section on Augmentation and the Menu/Link example:
import { Link } from 'react-router'
<Menu>
<Menu.Item as={Link} to='/home'>
Home
</Menu.Item>
</Menu>
Where they make the comment that:
Extra props are passed to the component you are rendering as.
And in this case the 'to' prop isn't one that would be recognised by the Menu.Item element but is one that the Link element would need.
Upvotes: 3
Views: 8104
Reputation: 4335
The problem is that the property 'onClick' doesn't exist on the strongly typed 'Table.Cell' element (whose props are determined by the TableCellProps interface) and so the code can't be compiled.
You should use Table.Cell
, it was fixed in 0.64.4, you can follow this work in the issue.
<Table.Cell onClick={handleClick} />
Upvotes: 4
Reputation: 865
In posting the question, one solution that I had overlooked which is considerably simpler is to make use of the TypeScript spread operator to add props from a strongly typed interface like this:
interface ExtraTableCellProps {
onClick?: React.EventHandler<React.MouseEvent<any>>;
}
and then from within render():
var myProps: ExtraTableCellProps = {
onClick: handleClick
};
return <Table.Cell className={cssClass} key={idx} {...myProps}>{txt}</Table.Cell>;
This achieves the goal without an additional level of React element nesting.
Upvotes: 1