2017-01-12 1 views
0

React VirtualizedのCollectionコンポーネントを使用して問題を解決できるのであれば、少し混乱します。私は自分が何をしているのかを説明しようとします:React Virtualized:同じ固定高さであるが幅が異なるセルを持つコレクション

私はページ上でReact Virtualizedを使って2つのリスト/アイテムのコレクションを表示しています。

Collection where cells have same height & width

最初のコレクションはかなりまっすぐ進むと、実装が容易だった:私は、同じ幅と高さを持っているアイテムを持っている最初のコレクションを終えました。 今私は様々なサイズの画像を含む第2のコレクションに取り組んでいます。私は、セルの高さは同じですが幅は異なります(画像の大きさによって異なります)。

Collection where cells have same height but different width

仮想化を実現すると反応するように、これは可能です:問題は、行は常に同じセルの数を持っていないかもしれないということですか?もしそうなら、どうすれば "cellSizeAndPositionGetter"の位置を知ることができますか?

+0

ショートA nswer:できません。私が考えることができる回避策は、実際の行にすべてのセルを分割することです。行1は最初の3つのイメージを持ち、行2はあなたの場合には次の4つを持ちます。次に、個々のセルではなく、行自体を仮想化します。これは、一般的な仮想化リスト(「グリッド」ではなく「リスト」)の「設計上の制約」です。 –

+0

私はSergiuが言ったことに同意します。もう少し追加するために、あなたが本当に示したトップコレクションは 'Component'ではなく' Grid'でなければなりません。 'Grid'はより効率的で簡単です。 2番目に表示されるものは 'List'でもかまいませんが、行数を計算するのはちょっと難しいでしょう。 – brianvaughn

+0

@brianvaughn私はあなたが 'Collection'を意味すると思いますが、' Component'ではありませんか?とにかく、私はあなたの両方が言っているものを見ます。最初のコレクションのために 'Grid'を試してみたいと思います。 2番目のコレクションについては、[CassetteRocks/react-infinite-scroller](https://github.com/CassetteRocks/react-infinite-scroller)を使用して終了しました。私は余裕を持って、React Virtualizedを使って2番目のコレクションを実装しようとします。私は本当にレポが好きだから! :)両方のあなたの入力をありがとう。 – Jooooooooohn

答えて

1

最近、固定高さの可変幅イメージカードの行を表示するのに、react-virtualizedListを使用しました。

私のListrowRendererはイメージカード要素の行の配列を使用します。つまり、JSXのような反応コンポーネントの配列の配列です。

要素の幅と画面の幅に基づいて行を構築する方法については、最終機能のcardsRowsを参照してください。ここで

は、それがどのように見えるかです:

List rows layout

は、この情報がお役に立てば幸い!

私のコードのいくつかのスニペット:

import {AutoSizer, List} from 'react-virtualized'; 

...

updateDimensions() { 
    this.setState({ 
     screenWidth: window.innerWidth, 
    }); 
} 

componentDidMount() { 
    window.addEventListener("resize", this.updateDimensions); 
} 


componentDidUpdate(prevProps, prevState) { 
    const props = this.props; 
    const state = this.state; 

    if (JSON.stringify(props.imageDocs) !== JSON.stringify(prevProps.imageDocs) || state.screenWidth !== prevState.screenWidth) 
     this.setState({ 
      cardsRows: cardsRows(props, state.screenWidth), 
     }); 
} 


rowRenderer({key, index, style, isScrolling}) { 
    if (!this.state.cardsRows.length) 
     return ''; 
    return (
     <div id={index} title={this.state.cardsRows[index].length} key={key} style={style}> 
      {this.state.cardsRows[index]} 
     </div> 
    ); 
} 

...

render() { 
    return (
      <div style={styles.subMain}> 
       <AutoSizer> 
        {({height, width}) => (<List height={height} 
               rowCount={this.state.cardsRows.length} 
               rowHeight={164} 
               rowRenderer={this.rowRenderer} 
               width={width} 
               overscanRowCount={2} 
         /> 
        )} 
       </AutoSizer> 
      </div> 
    ); 
} 

...

const cardsRows = (props, screenWidth) => { 

    const rows = []; 
    let rowCards = []; 
    let rowWidth = 0; 
    const distanceBetweenCards = 15; 

    for (const imageDoc of props.imageDocs) { 
     const imageWidth = getWidth(imageDoc); 

     if (rowWidth + distanceBetweenCards * 2 + imageWidth <= screenWidth) { 
      rowCards.push(cardElement(imageDoc)); 
      rowWidth += distanceBetweenCards + imageWidth; 
     } 
     else { 
      rows.push(rowCards); 
      rowCards = []; 
      rowWidth = distanceBetweenCards; 
     } 
    } 
    if (rowCards.length) { 
     rows.push(rowCards); 
    } 
    return rows; 
}; 


const styles = { 
    subMain: { 
     position: 'absolute', 
     display: 'block', 
     top: 0, 
     right: 0, 
     left: 0, 
     bottom: 0, 
    } 
}; 
関連する問題