Created
April 24, 2018 09:00
-
-
Save sunpietro/8c7a2681f4da445bb7c7de75a6ef8333 to your computer and use it in GitHub Desktop.
An example of ReactJS table that has sorting, pagination implemented using getDerivedStateFromProps
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from "react"; | |
import { render } from "react-dom"; | |
import { MemoizedFlow } from "react-memoize"; | |
const StatelessTable = ({ list, page, onPageChange, onSortChange }) => ( | |
<table border={1} cellPadding={5}> | |
<thead> | |
<tr> | |
<th># counter</th> | |
<th>data from "list"</th> | |
<th>data from "extra"</th> | |
</tr> | |
</thead> | |
<tbody> | |
{list.map(({ id, extra }, index) => ( | |
<tr> | |
<td>{index+page*10}</td> | |
<td>{id}</td> | |
<td>{extra}</td> | |
</tr> | |
))} | |
</tbody> | |
</table> | |
); | |
const genRandom = () => | |
Array(100) | |
.fill(1) | |
.map(x => Math.round(1000 * Math.random())); | |
class Table extends React.Component { | |
state = { | |
page: 0, | |
sortOrder: 1, | |
extraData: [], | |
extraSorting: true, | |
random: 0, | |
seedAddition: 0 | |
}; | |
sideEffect = () => Promise.resolve().then(this.setState({ extraData: genRandom() })); | |
render() { | |
return ( | |
<div> | |
This table is "flow" memoized | |
<MemoizedFlow | |
input={{ ...this.state, ...this.props }} | |
flow={[ | |
// could change list! | |
({ list, seedAddition }) => ({ list: list.map(id => + id + Math.round(10*Math.random()))}), | |
// side effect, react only on `random` change | |
({ random }) => this.sideEffect(random), | |
// map list numbers to object | |
({ list }) => ({ | |
list: list.map((line, index) => ({ | |
id: line | |
})) | |
}), | |
// mix with extra data from sideEffect BEFORE Sorting | |
({ list, extraData, extraSorting }) => extraSorting && ({ | |
list: list.map((line, index) => ({ | |
...line, | |
extra: extraData[index] | |
})) | |
}), | |
// sorting, react on data or sort order change | |
({ list, sortOrder }) => ({ | |
list: list.slice().sort((a, b) => sortOrder * (a.id - b.id)) | |
}), | |
// mix with extra data from sideEffect AFTER sorting | |
({ list, extraData, extraSorting }) => !extraSorting && ({ | |
list: list.map((line, index) => ({ | |
...line, | |
extra: extraData[index] | |
})) | |
}), | |
// pagination | |
({ list, page }) => ({ list: list.slice(page*10, page*10+10) }), | |
]} | |
> | |
{({ list, page }) => ( | |
<StatelessTable | |
list={list} | |
page={page} | |
onPageChange={this.onPageChange} | |
/> | |
)} | |
</MemoizedFlow> | |
<br /> | |
<br /> | |
changePage: | |
<select onChange={event => this.setState({ page: event.target.value})}> | |
{ Array(this.props.list.length/10).fill(1).map((i, index)=>( | |
<option value={index}>{index+1}</option> | |
))} | |
</select> and it will be applied without list regeneration | |
<br /><br /> | |
<button onClick={() => this.setState(state => ({ seedAddition: state.seedAddition + 1 }))}>Randomize</button> | |
only ONLY it will update EVERYTHING. | |
<br /><br /> | |
<button onClick={() => this.setState(state=>({random: state.random+1}))}>Apply side effect</button> to update extra | |
<br /><br /> | |
<button onClick={() => this.setState(state => ({ extraSorting: !state.extraSorting }))}>Flip extra sorting</button> to make extra applied before or after sorting | |
<br /><br /> | |
<button onClick={() => this.setState(state => ({ sortOrder: -state.sortOrder }))}>Flip sorting</button> just to change sort order | |
<br /><br /> | |
<button onClick={() => this.setState(state => ({ seedAddition: state.seedAddition + 1 }))}>Randomize</button> | |
only ONLY it will update EVERYTHING (keep in mind - data is sorted). | |
</div> | |
); | |
} | |
} | |
const randomData = genRandom(); | |
const App = () => ( | |
<div> | |
<Table list={randomData} /> | |
</div> | |
); | |
render(<App />, document.getElementById("root")); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment