web-dev-qa-db-fra.com

React-router: utilisation de <Link> comme ligne de tableau de données cliquable

Je suis nouveau dans l'utilisation de ReactJS et de react-router. Je veux une ligne de tableau cliquable et quelque chose comme la configuration suivante:

<Link to=“#”>
<tr>
    <td>{this.props.whatever1}</td>
    <td>{this.props.whatever2}</td>
    <td>{this.props.whatever3}</td>
</tr>
</Link>

mais je sais que vous ne pouvez pas mettre <a> balises entre les <tbody> et <tr> Mots clés. Sinon, comment puis-je accomplir cela?

PS: je préfère ne pas utiliser jQuery si possible.

18
jfrye

Pourquoi n'utilisez-vous pas simplement 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>
    );
  }
});
5
Sergio Flores

onClick fonctionne, mais parfois vous avez besoin d'une réelle <a> tag pour diverses raisons:

  • Accessibilité
  • Amélioration progressive (si le script génère une erreur, les liens fonctionnent toujours)
  • Possibilité d'ouvrir un lien dans un nouvel onglet
  • Possibilité de copier le lien

Pour un cas similaire, j'ai fini par créer un composant Td:

import React, { PropTypes } from 'react';
import { Link } from 'react-router';

import styles from './styles.css';

const propTypes = {
  children: PropTypes.node.isRequired,
  to: PropTypes.string,
};

function Td({ children, to }) {
  // Conditionally wrapping content into a link
  const content = to ? (
    <Link className={styles.content} to={to}>{children}</Link>
  ) : (
    <div className={styles.content}>{children}</div>
  );

  return (
    <td>
      {content}
    </td>
  );
}

Td.propTypes = propTypes;

export default Td;

Styles pour que le bouton remplisse la cellule entière:

.content {
  display: block;
  color: inherit;
  padding: 5px 10px;
}

Utilisez ensuite le composant comme ceci:

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>
    );

Oui, vous devrez passer to prop plusieurs fois, mais en même temps, vous avez plus de contrôle sur les zones cliquables et vous pouvez avoir d'autres éléments interactifs dans le tableau, comme des cases à cocher.

16
Igor Barbashin