在Firefox中动态设置React渲染表的高度与Chrome不同

时间:2018-03-13 11:30:53

标签: javascript reactjs google-chrome firefox offsetheight

目前在React项目上工作,使用webpack,webpack-dev-server,热模块重装,React路由器,样式组件等

我创建了一个Table组件,我尝试根据父级的高度动态确定在Table中呈现的行数。在Chrome中,这可以按预期工作,但在Firefox中我发现我的所有行都被渲染,因此不会绑定在父组件中。

这是一个已知问题,还是有任何建议的解决方法或我的代码有什么可怕的错误?

父组件(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>
);

表组件:

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

提前致谢!

1 个答案:

答案 0 :(得分:1)

也许不是我一直在寻找的答案,但最后我将动态numberOfRowsToDisplay设置为组件状态的一部分;这给了我正在寻找的UI结果