Skip to content

Instantly share code, notes, and snippets.

@MalucoMarinero
Last active November 25, 2016 02:40
Show Gist options
  • Save MalucoMarinero/03b52f7ff71f5cccebe0e5c54749d33d to your computer and use it in GitHub Desktop.
Save MalucoMarinero/03b52f7ff71f5cccebe0e5c54749d33d to your computer and use it in GitHub Desktop.
Demonstrating style comparison shallow vs stringify
/** @flow */
import cn from 'classnames'
import Immutable from 'immutable'
import React, { Component, PropTypes } from 'react'
import { ContentBox, ContentBoxHeader, ContentBoxParagraph } from '../demo/ContentBox'
import WindowScroller from './WindowScroller'
import List from '../List'
import AutoSizer from '../AutoSizer'
import shallowCompare from 'react-addons-shallow-compare'
import styles from './WindowScroller.example.css'
export default class AutoSizerExample extends Component {
static contextTypes = {
list: PropTypes.instanceOf(Immutable.List).isRequired
}
constructor (props) {
super(props)
this._rowRenderer = this._rowRenderer.bind(this)
}
render () {
const { list } = this.context
return (
<ContentBox>
<ContentBoxHeader
text='WindowScroller'
sourceLink='https://github.com/bvaughn/react-virtualized/blob/master/source/WindowScroller/WindowScroller.example.js'
docsLink='https://github.com/bvaughn/react-virtualized/blob/master/docs/WindowScroller.md'
/>
<ContentBoxParagraph>
This component decorates <code>List</code>, <code>Table</code>, or any other component
and manages the window scroll to scroll through the list
</ContentBoxParagraph>
<div className={styles.WindowScrollerWrapper}>
<WindowScroller>
{({ height, isScrolling, scrollTop }) => (
<AutoSizer disableHeight>
{({ width }) => (
<List
autoHeight
className={styles.List}
height={height}
rowCount={list.size}
rowHeight={30}
rowRenderer={({ index, key, style }) => this._rowRenderer({ index, isScrolling, key, style })}
scrollTop={scrollTop}
width={width}
/>
)}
</AutoSizer>
)}
</WindowScroller>
</div>
</ContentBox>
)
}
shouldComponentUpdate (nextProps, nextState) {
return shallowCompare(this, nextProps, nextState)
}
_rowRenderer ({ index, isScrolling, key, style }) {
const { list } = this.context
const row = list.get(index)
const className = cn(styles.row, {
[styles.rowScrolling]: isScrolling
})
return (
<RowComponent
key={key}
rowKey={key}
// className={className}
// am aware this removes the 'isScrolling' behaviour, but the plus side is we end up with ZERO updates on
// the row component, only create and destroy, which feels like the most optimal as far as DOM hits. Ideally if
// style had referential equality we could still use isScrolling anyway
style={style}
name={row.name}
/>
)
}
}
class RowComponent extends Component {
// many renders every scroll tick, updates and creations
// shouldComponentUpdate (nextProps, nextState) {
// return shallowCompare(this, nextProps, nextState)
// }
// only creations on scroll tick, never updates
shouldComponentUpdate (nextProps, nextState) {
if (JSON.stringify(this.props.style) !== JSON.stringify(nextProps.style)) {
return true;
} else {
return (
this.props.name !== nextProps.name ||
this.props.className !== nextProps.className ||
this.props.rowKey !== nextProps.rowKey
)
}
}
componentDidUpdate (prevProps) {
if (this.props.style !== prevProps.style) {
console.log("style has changed for: " + this.props.rowKey)
}
}
render () {
const { name, className, style } = this.props;
return (
<div
className={className}
style={style}
>
{name}
</div>
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment