react-table -- how to set background color for column headers only
check this code here
https://codesandbox.io/s/silent-fog-yprqd4?file=/src/App.js
th {
background-color: red;
}
the th
tag is styled with a style variable
ReactJS 7 - How to conditionally change the background color of table cell only (not the row) based on its value?
The docs say you can set conditional styles like this: https://www.npmjs.com/package/react-data-table-component#conditional-style-object
const conditionalRowStyles = [
{
when: row => row.calories < 300,
style: {
backgroundColor: 'green',
color: 'white',
'&:hover': {
cursor: 'pointer',
},
},
},
// You can also pass a callback to style for additional customization
{
when: row => row.calories < 300,
style: row => ({
backgroundColor: row.isSpecia ? 'pink' : 'inerit',
}),
},
];
const MyTable = () => (
<DataTable
title="Desserts"
columns={columns}
data={data}
conditionalRowStyles={conditionalRowStyles}
/>
);
I quickly put together an example usings cell and styled components:
https://codesandbox.io/s/upbeat-galileo-r7p34?file=/src/App.js
import "./styles.css";
import DataTable from "react-data-table-component";
import styled from "styled-components";
const StyledCell = styled.div`
&.low {
background: green !important;
}
&.medium {
background: orange;
}
&.high {
background: red !important;
}
`;
export default function App() {
let items = [
{
Country: "Canada",
AdditionalNewCases: 500
},
{
Country: "England",
AdditionalNewCases: 5000
},
{
Country: "USA",
AdditionalNewCases: 500000
}
];
function getCssClass(value) {
if (value > 5000) return "high";
else if (value > 500) return "medium";
return "low";
}
return (
<DataTable
title="Covid-19 Stats"
defaultSortAsc="false"
responsive
defaultSortAsc={false}
striped
highlightOnHover
data={items}
columns={[
{
name: "number",
selector: (row, index) => index + 1,
disableSortBy: true
},
{
name: "Country",
selector: "Country",
sortable: true
},
{
name: "New Cases",
selector: "AdditionalNewCases",
sortable: true,
cell: (row) => (
<StyledCell className={getCssClass(row.AdditionalNewCases)}>
{row.AdditionalNewCases}
</StyledCell>
)
}
]}
/>
);
}
React: How to change Table cell background depending on cell value in React table
Just use a ternary operator and pass a class or value in
<td key="Questions" className={value > 0.25 ? 'greenclass' : 'redclass' }>
or
<td key="Questions" styles={{ background: value > 0.25 ? 'green' : 'red' }}>
Update for 3+ classes
I would use an outside function where you have an if/else or switch statement return className
Have this function outside the render
resolveClass = (value) => {
let className = ''
switch (true) {
case (value > 0.25):
className = 'green'
break;
case (value < 0):
className = 'red'
break;
default:
break
}
return className
}
Then inside the render <td key="Questions" className={resolveClass(paa.Questions)}>
Update cell background color when deleting the row. (react-table)
The main cause of this issue is keys. To learn more about how to use keys, you can check out React's official documentation here: https://reactjs.org/docs/lists-and-keys.html#keys
The main cause of this inconsistency is the code here
<tbody {...getTableBodyProps()}>
{page.map((row, i) => {
prepareRow(row)
return (
<ClickAndHold id={i} elmType={'tr'} onHold={e => openContextMenu(e, row)} {...row.getRowProps()} onContextMenu={e => openContextMenu(e, row)}>
{row.cells.map(cell => {
return <td {...cell.getCellProps([getCellProps(cell)])}>{cell.render('Cell')}</td>
})}
</ClickAndHold>
)
})}
</tbody>
The ClickAndHold
component is passed the props from row.getRowProps()
. row.getRowProps()
returns an object that contains a key that looks something like row_0
. Now, this key is dependent upon the row's position in the table. Suppose there were five rows, then their keys would be row_0
, row_1
, row_2
, row_3
, and row_4
. If you deleted the 4th row (with key row_3
), the fifth row (with key row_4
) would get the fourth row's key. Suppose that you actually deleted the fourth row, then the keys would look like this: row_0
, row_1
, row_2
, row_3
. So, now, the fifth row (which previously had key row_4
, but now has key row_3
), has fourth row's key. Thus, when react re renders your tree, it'll pass the fourth row's props to fifth row. This means that if the fourth row had blue background, then fifth row will also have blue background. I know this is a handful, but I hope I'm making sense here.
To get around this issue, you need to pass a unique key to the row. This unique key should ideally come from the data that you're rendering. If I look at your data, you have an id
that is unique. So, use this id
as a key for ClickAndHold
component. Summarizing everything, to resolve this issue, you need to edit the code as
<tbody {...getTableBodyProps()}>
{page.map((row, i) => {
prepareRow(row)
return (
<ClickAndHold id={i} elmType={'tr'} onHold={e => openContextMenu(e, row)} {...row.getRowProps()} key={row.original.id} onContextMenu={e => openContextMenu(e, row)}>
{row.cells.map(cell => {
return <td {...cell.getCellProps([getCellProps(cell)])}>{cell.render('Cell')}</td>
})}
</ClickAndHold>
)
})}
The row
object inside the page
list contains an original
object that contains your data. So, you simply need to use id
from your custom data, and use it as key
. You need to pass key
after {...row.getRowProps()}
to override the key returned by row.getRowProps()
.
I've tested this in your codesandbox, and over there you simply need to edit the tr
component found in line 85 inside CustomTable.jsx
in this way.
<tr
id={i}
{...row.getRowProps()}
key={row.original.id}
onContextMenu={(e) => openContextMenu(e, row)}
>
I hope that's helpful.
Another suggestion, in your code for adding new row, you're chaning all the ids that come after the newly added row. This is code for reference.
setTableData((sequence) => {
const newData = sequence.reduce((acc, step) => {
if (incrementId) {
step.id = step.id + 1;
acc.push(step);
} else {
acc.push(step);
}
if (step.id === nextToId) {
newStep.id = newStep.id + 1;
acc.push(newStep);
incrementId = true;
}
return acc;
}, []);
return newData;
});
This will cause inconsistency because when you change id
which is used as key for a row, on next re render, react will pass props to the newly added row that belonged to the previous row that the newly added row replaced. To learn more about this, check out this article: https://robinpokorny.medium.com/index-as-a-key-is-an-anti-pattern-e0349aece318. What I'm trying to say is, keys should be unique for every component inside the list, and if a component is added or deleted, any other component cannot take its key. You can use uuid for generating unique keys. Take a look here for how to use uuid https://www.npmjs.com/package/uuid.
Essentially, you need to be careful with dealing with keys, otherwise you risk severely degrading the performance of your application, or messing up the state of your component tree.
UPDATE
Sorry, but I was wrong about the root cause of this issue. Though it's true that there's a problem with the way you're using keys, the background color issue is not solely due to it. In fact, what causes background color to not change is because you set background-color: none
. background-color
doesn't have a property called none. So, this is an invalid CSS property, and it doesn't get updated in the DOM. This causes previously valid background-color to linger around, thus causing the issue. To fix this, you probably want to set background-color: unset
or background-color: white
when you want to remove the blue background. Hope that helps!
How to color specific cells in Table
You can use something like
<tr style={{'background-color': result.color}}>...</tr>
or
<tr style={{'background-color': shouldHighlight[key] ? 'red' : 'white'}}>...</tr>
Obviously in second case you need to findout before function, which table rows should be highlighted and store it in the array.
Also, you need to write your map function in format (result, key) => ...
or you need to know id of the result.
Related Topics
Typescript Property Does Not Exist on Type {}
Validate Phone Number With Yup
Make Discord Bot Send Picture With Message With Nodejs
Change Specific Button Text on Click Inside Ngfor
Javascript Generate Video Thumbnail from Video Url
How to Get the Index from a Json Object With Value
How to Format Numbers by Prepending 0 to Single-Digit Numbers
How to Use Zindex in React-Native
Add Hyphen After Every Fourth Character in a String Seperated by Comma
Delete Span Tag Along With Text in HTML Permanently
Increase Counter Value Upon Button Click
How to Access the Value of a Promise
How to Count Unique Value from Object of Array in JavaScript
Save Only Date Without Timezone JavaScript
Jest Encountered an Unexpected Token: Syntaxerror: Unexpected Token {
How to Validate Mobile Number for Countries in Angular