0

I am using react ultimate pagination to make a pagination functionality. When a page number is clicked I am updating a variable to show what is needed. The problem is that I have a loop which can have variable number of elements, so I do not know how many of them are there in advance. Here is the code:

{
      this.state.fullAnalysisDone && this.state.activeKey == 3 ? 
      <div>
      {
        this.get_analysis_charts(this.chartTypes[parseInt(this.state.activeKey)]).map((chart_arr, idx) => {
          return <div style={{visibility: this.state.currPageDiffGenes === (idx + 1) ? 'visible' : 'hidden' }}>
            <img src = {chart_arr[0]} style = {{height:"400px", width:"500px"}}/>
            <img src = {chart_arr[1]} style = {{height:"400px", width:"500px"}}/>
            </div>
        })
      }
        <div style = {{marginLeft: '35%'}}>
          <UltimatePaginationBootstrap4 key = 'diff_genes_pagination' 
                          totalPages = {this.get_analysis_charts(this.chartTypes[parseInt(this.state.activeKey)]).length}
                          onChange = {this.changedDiffGenes}
                          currentPage = {this.state.currPageDiffGenes}/>
        </div>    
      </div>
    : ""
  }

I can not really leave here <div style={{visibility: this.state.currPageDiffGenes === (idx + 1) ? 'visible' : 'hidden' }}> because it takes space on the page. If I knew beforehand the number of iterations, I could have just done the following:

{
        this.state.currPageDiffGenes === 1 ?
        loop over but return only the 1st element
       :""
}

{
        this.state.currPageDiffGenes === 2 ?
        loop over but return only the 2nd element
        :""
}

...

And it would work because elements would be recreated each time, but I can not do it with variable length loop. How could we solve this issue? I am using d3 in the app, so I can just assign ids to the respective divs, and maybe destroy-insert elements while using pagination, but I feel like that is overkill and there should be an easier solution.

Nikita Vlasenko
  • 4,004
  • 7
  • 47
  • 87

1 Answers1

0

Currently I solved it using D3 using display property, but it may be against React-way of doing things. It is working, but I would prefer a different solution if there is one:

changedDiffGenes = (pageNum) => {
  let prevId = '#diff_chart_' + (this.state.currPageDiffGenes - 1);
  let currId = '#diff_chart_' + (pageNum - 1);
  d3.select(prevId).style("display","none");
  d3.select(currId).style("display","block");
  this.setState({
    currPageDiffGenes: pageNum
  })
}

{
        this.get_analysis_charts(this.chartTypes[parseInt(this.state.activeKey)]).map((chart_arr, idx) => {
          return <div id = {'diff_chart_' + idx} style={{display: idx === 0 ? 'block' : 'none', 
                    visibility: this.state.currPageDiffGenes === (idx + 1) ? 'visible' : 'hidden' }}>
            <img src = {chart_arr[0]} style = {{height:"200px", width:"300px"}}/>
            <img src = {chart_arr[1]} style = {{height:"200px", width:"300px"}}/>
            </div>
        })
      }
       <div style = {{marginLeft: '35%'}}>
          <UltimatePaginationBootstrap4 key = 'diff_genes_pagination' 
                          totalPages = {this.get_analysis_charts(this.chartTypes[parseInt(this.state.activeKey)]).length}
                          onChange = {this.changedDiffGenes}
                          currentPage = {this.state.currPageDiffGenes}/>
        </div>  

So, inside the function onChange = {this.changedDiffGenes} that is invoked by UltimatePaginationBootstrap4 (which is the code copy-pasted from the react-ulitmate-pagination github page) I am switching back and forth display property between block and none. It is certainly easier than insert/delete elements using d3 and I found the relevant solution here: How to hide elements without having them take space on the page?

Nikita Vlasenko
  • 4,004
  • 7
  • 47
  • 87