React-router: Using <Link> as clickable data table row

Why don't you just use onClick?

var ReactTable = React.createClass({
  handleClick: function(e) {
    this.router.transitionTo('index');
  },
  render: function() {
    return(
      <div>
        <table>
          <thead>
            <tr>
              <th>Name</th>
              <th>Age</th>
              <th>Full Detail</th>
            </tr>
          </thead>
            <tbody>
              <tr onClick={this.handleClick.bind(this)}>
                <td>{user.name}</td>
                <td>{user.age}</td>
                <td>{details}</td>
              </tr>
            </tbody>
        </table>
      </div>
    );
  }
});

onClick works, but sometimes you need an actual <a> tag for various reasons:

  • Accessibility
  • Progressive enhancement (if script is throwing an error, links still work)
  • Ability to open a link in new tab
  • Ability to copy the link

Here's an example of a Td component that accepts to prop:

import React from 'react';
import { Link } from 'react-router-dom';

export default function Td({ children, to }) {
  // Conditionally wrapping content into a link
  const ContentTag = to ? Link : 'div';

  return (
    <td>
      <ContentTag to={to}>{children}</ContentTag>
    </td>
  );
}

Then use the component like this:

const users = this.props.users.map((user) =>
      <tr key={user.id}>
        <Td to={`/users/${user.id}/edit`}>{user.name}</Td>
        <Td to={`/users/${user.id}/edit`}>{user.email}</Td>
        <Td to={`/users/${user.id}/edit`}>{user.username}</Td>
      </tr>
    );

Yes, you'll have to pass to prop multiple times, but at the same you have more control over the clickable areas and you may have other interactive elements in the table, like checkboxes.