working on a React project currently, using webpack, webpack-dev-server, hot module reloading, React Router, styled-components etc
I have created a Table component where I try to dynamically determine the number of rows to render within the Table based on the height of the parent. Within Chrome, this works as expected, but in Firefox I am finding that all my rows are being rendered and therefore are not bound within the parent component.
Is this a known issue or are there any suggested workarounds or is there something horrendously wrong with my code?
Parent component (App):
const MainContainer = styled.div`
background-color: ${colours.white};
border-radius: 4px;
box-shadow: 0 0 9px 0 #dedede;
display: flex;
flex-wrap: wrap;
height: 85%;
width: 92.5%;
`;
const InnerContainer = styled.div`
display: flex;
flex-direction: column;
width: calc(100% - 9.375em);
`;
const SearchAndCountPlaceholder = styled.div`
height: 12.5%;
`;
const SidebarPlaceholder = styled.div`
background-color: ${colours.blue.light};
height: 100%;
opacity: 0.12;
width: 9.375em;
`;
const LoadMoreButtonContainerPlaceholder = styled.div`
height: 15%;
`;
const App = () => (
<MainContainer className="app-component">
<SidebarPlaceholder />
<InnerContainer>
<SearchAndCountPlaceholder />
<Table tableHeadings={tableHeadings} masterData={mockData} />
<LoadMoreButtonContainerPlaceholder />
</InnerContainer>
</MainContainer>
);
Table component:
const Container = styled.div`
background-color: ${colours.white};
height: 100%;
overflow-x: scroll;
padding-bottom: 1em;
width: 100%;
`;
const StyledTable = styled.table`
border-bottom: 2px solid ${colours.grey.lighter};
border-collapse: collapse;
margin: 1.25em;
table-layout: fixed;
width: 100%;
& thead {
border-bottom: inherit;
color: ${colours.grey.lighter};
font-size: 0.75em;
font-weight: 700;
line-height: 1em;
text-align: left;
text-transform: uppercase;
& th {
padding: 0.75em 1em 0.75em 1em;
width: 7.25em;
}
& th:not(.Source) {
cursor: pointer;
}
& span {
color: ${colours.blue.dark};
font-size: 1em;
font-weight: 300;
margin-left: 0.313em;
}
}
& tbody {
color: ${colours.grey.dark};
font-size: 0.813em;
line-height: 1.125em;
& tr {
border-bottom: 1px solid ${colours.grey.lightest};
& td {
padding: 1em;
}
}
& .masterData {
font-weight: 700;
}
}
`;
let numberOfRowsToDisplay;
const calculateNumberOfRowsToDisplay = () => {
const tableHeight = document.querySelector('.table-component').offsetHeight;
const rowHeight = 40; // height of row in pixels
const numberOfRowsNotToIncludeInCalculation = 2; // header & scrollbar
numberOfRowsToDisplay = Math.floor(
tableHeight / rowHeight - numberOfRowsNotToIncludeInCalculation
);
};
class Table extends Component {
constructor(props) {
super(props);
this.state = { columnToSort: '' };
this.onColumnSortClick = this.onColumnSortClick.bind(this);
}
componentDidMount() {
calculateNumberOfRowsToDisplay();
}
onColumnSortClick(event) {
event.preventDefault();
const columnToSort = event.target.className;
this.setState(prevState => {
if (prevState.columnToSort === columnToSort) {
return { columnToSort: '' };
}
return { columnToSort };
});
}
render() {
const { tableHeadings, masterData } = this.props;
const { columnToSort } = this.state;
const upArrow = '⬆';
const downArrow = '⬇';
return (
<Container className="table-component">
<StyledTable>
<thead>
<tr>
{tableHeadings.map(heading => (
<th
className={heading}
key={heading}
onClick={this.onColumnSortClick}
>
{heading}{' '}
{heading !== 'Source' ? (
<span>
{heading === columnToSort ? upArrow : downArrow}
</span>
) : null}
</th>
))}
</tr>
</thead>
<tbody>
{masterData &&
masterData.slice(0, numberOfRowsToDisplay).map(data => {
const dataKey = uuidv4();
return (
<tr className="masterData" key={dataKey}>
<td>Master</td>
{Object.values(data).map(datum => {
const datumKey = uuidv4();
return <td key={datumKey}>{datum}</td>;
})}
</tr>
);
})}
</tbody>
</StyledTable>
</Container>
);
}
}
Thanks in advance!