Skip to content

Instantly share code, notes, and snippets.

@tobyS
Created November 30, 2018 14:21
Show Gist options
  • Save tobyS/9670c1ba1ef3fb1f371e2de21209e975 to your computer and use it in GitHub Desktop.
Save tobyS/9670c1ba1ef3fb1f371e2de21209e975 to your computer and use it in GitHub Desktop.
Circular data cycle with range slider UI component in ReactJS
class PriceRange extends PureComponent {
constructor (props) {
super(props)
this.state = {
range: null,
}
}
// Overwrites the state if page just loaded or other
// component changed the URL
static getDerivedStateFromProps = (props, state) => {
if (!state.range || !props.valueFromComponent) {
return {
range: [
props.value.min,
props.value.max,
],
}
}
return null
}
render () {
// Actual range slider UI element (https://github.com/react-component/slider)
return (<Range
value={this.state.range}
onChange={(range) => {
this.updateRange(range)
}}
/>)
}
updateRange = (range) => {
this.setState({
range: _.cloneDeep(range),
}, this.updateUrl)
}
updateUrl = _.debounce(() => {
app.getRouter().push(
app.getRouter().route,
{
min: this.state.range[0],
max: this.state.range[1],
},
// Indicate in URL state that this
{ valueFromComponent: true }
)
}, 100)
}
@joernb
Copy link

joernb commented Jan 4, 2019

Looks like a missing application logic layer between UI components and external side effects like browser url changes. This can be solved with Redux by separating the "component <-> browser url" sync into "component <-> store" and "store <-> browser url". The former can be implemented with Reducers and the connect() function of react-redux. The latter handles the side effect and can be implemented with a custom Redux middleware. The middleware should react to Redux actions indicating a slider change by changing the browser url. It should also monitor url changes and emit certain Redux actions to which the Reducer mentioned above can react to which consequently will trigger a rerender of connected components. The middleware might also take care of the whole debouncing stuff. If you are looking for a way how to handle url sync the Redux way, you might wanna take a look at connected-react-router which is basically just a Redux binding for react-router.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment