developerdizzle / react-virtual-list

Super simple virtualized list React component
http://developerdizzle.github.io/react-virtual-list/
MIT License
617 stars 71 forks source link

VirtualScroller and forceUpdateGrid do not call rowHeight function #36

Closed BossGrand closed 8 years ago

BossGrand commented 8 years ago

Hi! I love your project, its awesome!!!

I think I've run into a bug, or I'm doing something incorrectly because I can't get forceUpdateGrid to run the rowHeight function.

I have a list of components that can be expanded to see more info at which point i try to call the forceUpdateGrid function but it doesn't have an effect.

import React from 'react'

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

import DealroomBuilding from '../../containers/broker_dashboard/DealroomBuilding';

const DealroomStateList = React.createClass({

    getInitialState(){
        return {
            buildings_expanded: {},
            buildings_hiding_listings: {},
           row_count: this.props.building_ids.length,
        }
    },

_onBuildingExpandToggle(b_id, is_expanded){
    var self = this;

    var buildings_expanded = this.state.buildings_expanded;
    buildings_expanded[b_id] = is_expanded;

    this.setState({buildings_expanded}, 
        ()=>{

            self.refs.auto_sizer.refs.scroller.forceUpdateGrid();
        }
    );

},

_onShowListingsToggle(b_id, is_showing){
    var self = this;

    var buildings_hiding_listings = this.state.buildings_hiding_listings;
    buildings_hiding_listings[b_id] = !is_showing;

    //hack because i can't get virtual scroller to forceupdate (the index check part) 
    //  so i have to update one of the properties of the virtualscroller
    var row_count = this.state.row_count+1;

    this.setState({buildings_hiding_listings, row_count}, 
        ()=>{
            self.setState({
                row_count: row_count-1,
            })
        }
    );
},

_getVirtualScrollRow({index, isScrolling}){
    if(index === 0){
        return this._getDLCounterHtml();
    }
    return this._getDealroomBuildingHtml(index-1);
},
_getDLCounterHtml(){
    return(
        <div>
            <div className='content-title' style={{'display': 'inline-block'}}>
                {this.props.dl_count} {this.props.title}
            </div>
            <div style={{'display': 'inline-block'}}> 
                {this.props.children?
                    <span >   
                        {this.props.children}
                    </span>
                    :
                    null
                }
            </div>
        </div>
    )
},
_getDealroomBuildingHtml(index){
    const building_ids = this.props.building_ids;

    const b_id = building_ids[index];

    return(
        <DealroomBuilding key={b_id} id={b_id}
            onBuildingExpandToggle={this._onBuildingExpandToggle} 
            onShowListingsToggle={this._onShowListingsToggle}
        />
    )

},

_getRowHeight({index}){
    if(index === 0 || index > this.props.building_ids.length){
        return 50;
    }

    const{
        buildings_expanded,
        buildings_hiding_listings,
    } = this.state;

    const b_id = this.props.building_ids[index - 1];

    var height = 39;

    if(buildings_expanded[b_id]){
        height += 193;
    }
    else{
        height += 59;
    }

    if(!buildings_hiding_listings[b_id]){
        return height + 100;
    }

    return height

},

render(){
    return(
        <div className='content'>
            <AutoSizer ref='auto_sizer'>
                {({ height, width }) =>{ return(
                    <VirtualScroll
                    ref='scroller'
                    rowCount={this.state.row_count + 1}
                    rowHeight={this._getRowHeight}
                    rowRenderer={this._getVirtualScrollRow}
                    height={height}
                    width={width}
                  />
                )}}
              </AutoSizer>

        </div>  
    )
}
});

export default DealroomStateList;

the hack I've used to get around this is to have rowCount as a state variable which i increment then decrement to force the virtualscroller to have to rerender since its props change.

The hack is being used in _onShowListingsToggle. When that function is called everything works perfectly and the list is resized appropriately.

However when _onBuildingExpandToggle is called I call forceGridUpdate and nothing happens. I put a break point inside _getRowHeight, but its never called

developerdizzle commented 8 years ago

Hey @BossGrand ! Looking at your code, I think the repo you're looking for is actually https://github.com/bvaughn/react-virtualized

BossGrand commented 8 years ago

Oh my, thats embarrassing! Thank you for pointing me to the right place! haha