Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Using React Router's <Link /> to wrap a table row #2336

Answered by GuptaSiddhant
LydiaF asked this question in General
Discussion options

Hi there,

Thank you for such a great library.

I am running into a strange issue when I wrap a row with the component from react router. I have tried to see how to do this but I can't find something. I apologise if I missed something.

Thank you for any help :)

Before:

image

After:

image

<tr {...row.getRowProps()} className="cursor-pointer hover:bg-gray-50">
 <Link to={`/use-cases/${row.original.id}`}>
 {row.cells.map(cell => {
 if (cell.column.Header === 'Level') {
 return (
 <td {...cell.getCellProps()} className="px-6">
 <Badge text={useCaseLevels[cell.value]} />
 </td>
 )
 } else if (cell.column.Header === 'Epics') {
 return (
 <td {...cell.getCellProps()} className="px-6">
 {cell.value.map(v => <Badge text={v.epic.name} key={v.epic.name} />)}
 </td>
 )
 } else {
 return (
 <td
 {...cell.getCellProps()}
 className={`${cell.column.Header === 'Name' ? 'text-indigo-600 font-medium' : 'text-gray-500'} px-6 py-4 whitespace-no-wrap text-sm leading-5`}
 >
 {cell.render('Cell')}
 </td>
 )
 }
 })}
 </Link>
 </tr>
You must be logged in to vote

Unfortunately you can't do this. This is not react-table's issue.
This is an HTML issue which requires td to be direct children of tr. All other elements like div or Link should be inside td.

But as I can you want link the whole row. You can use the onClick prop on tr to achieve the same result. The catch is you have to use history api to manipulate your browser.

import { useHistory } from "react-router-dom";
const Table = () => {
 ...
 const history = useHistory();
 const handleRowClick = (row) => {
 history.push(`/use-cases/${row.original.id}`);
 } 
 return (
 ...
 <tr onClick={()=> handleRowClick(row)}}>
 ...
 </tr>
 ...
 );
}

Replies: 8 comments 12 replies

Comment options

Maybe try giving the Link 100% width? It's hard to say without a working example

You must be logged in to vote
1 reply
Comment options

Dear @dbertella Thank you for your suggestion but Gupta's below did the trick!

Comment options

Unfortunately you can't do this. This is not react-table's issue.
This is an HTML issue which requires td to be direct children of tr. All other elements like div or Link should be inside td.

But as I can you want link the whole row. You can use the onClick prop on tr to achieve the same result. The catch is you have to use history api to manipulate your browser.

import { useHistory } from "react-router-dom";
const Table = () => {
 ...
 const history = useHistory();
 const handleRowClick = (row) => {
 history.push(`/use-cases/${row.original.id}`);
 } 
 return (
 ...
 <tr onClick={()=> handleRowClick(row)}}>
 ...
 </tr>
 ...
 );
}
You must be logged in to vote
8 replies
Comment options

Thank you GuptaSiddhant for the simple solution. Very helpful.

Comment options

I really appreciate your efforts :) thanks a loot

Comment options

But I think now it is replaced with useNavigate()

Comment options

If you use onClick, wouldn't that mean you can't ctrl+click, or even have the contextual menu actions? It's kinda bad for user experience. Haven't really found a way to use onClick and yet still have the entire tr clickable.

Comment options

This is still working, but useHistory is deprecated, change to useNavigate instead. Some syntax change like

const history = useHistory(); 
history.push(`/use-cases/${row.original.id}`);

to

const navigate = useNavigate(); 
navigate(`/use-cases/${row.original.id}`);
Answer selected by LydiaF
Comment options

GuptaSiddhant thanks for your solution.

In case anyone is trying to enable a cmd/ctrl click to open in a new tab

Checking the event for a cmd/ctrl click worked for me.

<tr
 key={row.id}
 className={styles.row}
 {...row.getRowProps()}
 onClick={(event) =>{
 if (event.metaKey || event.ctrlKey){
 const win = window.open( `/audio-content/${row.original.id}`, "_blank");
 win?.focus();
 }
 else {
 history.push(
 `/audio-content/${row.original.id}`,
 )
 }
 }
 }>
You must be logged in to vote
2 replies
Comment options

Thanks @jackbridger I was looking for this as well :D

Comment options

@jackbridger would you be able to explain what win?.focus() does? I've removed it and the functionality stays the same. It seems that default functionality of window.open is to open the new tab in the"background" already without the need to include the win?.focus()?

The reason I am asking is because I would like to have the same functionality for a cmd/ctrl click when the middle mouse button is clicked. Replicating the above when listening for a middle mouse click doesn't seem to work. Any suggestions appreciated :)

Comment options

In React Router Dom V.6. you can do the following

import { useNavigate } from "react-router-dom";
const Table = () => {
 ...
 const navigate = useNavigate();
 const goRouteId = (id) => {
 navigate(`/${id}`);
 } 
 return (
 ...
 <tr onClick={()=> goRouteId(id)}}>
 ...
 </tr>
 ...
 );
}
You must be logged in to vote
0 replies
Comment options

After more thought on this subject, I’m pretty sure my first recommendation would be to not make the entire row a clickable link. Instead, I would make one or two main elements of the row like the first two cells clickable links and make it obvious that they are clickable. Only after considering that, would I recommend conditionally rendering special markup and event handlers for links.

You must be logged in to vote
0 replies
Comment options

Espero le sirva esto a la comunidad que usa TS:
En mi caso, yo tengo que consumir un api, en este caso cree una de prueba, para simular su consumo
image

Luego cree su interface:
data ts-2022年11月06日-04-02-39

Ya, ahora si vamos a lo que necesitamos, en mi caso estoy usando la Plantilla básica que te da React-Table v8
TablesTest tsx-2022年11月06日-04-03-30
Lo que hice fue colocar mi tipado en la solicitud, para luego consumirla en Accesor, simplemente dando un recorrido

Y por ultimo, para colocar el link, solo en una columna, hice lo siguiente:
TablesTest tsx-2022年11月06日-04-05-02

Teniendo en mente que cell tiene todos los valores, le di un recorrido hasta conseguir hasta conseguir el id de mi fila, claramente la etiqueta ancle, la puedes cambiar por Link de React y asimismo la parte de /test/ la cambiar al lugar que te quiera dirigir,
ESTE ES EL RESULTADO FINAL: (Claramente si le doy click al row2, el test cambiaria a /test/2 y así sucesivamente)
image

You must be logged in to vote
0 replies
Comment options

This helped me: stackoverflow.com/a/62451524/15172167
Solution: wrap each row and add onClick event with onRow prop

You must be logged in to vote
1 reply
Comment options

@amir2mi that solution is for antd table, how do you use it with tanStack table?

Comment options

You shouldn't wrap the tr with a Link or vice-versa. Instead, just render the Link as an element that behaves like a table row:

<Link {...row.getRowProps()} className="hover:bg-gray-50 table-row" href="/some/place">
You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

AltStyle によって変換されたページ (->オリジナル) /