Created
November 30, 2018 14:21
-
-
Save tobyS/9670c1ba1ef3fb1f371e2de21209e975 to your computer and use it in GitHub Desktop.
Circular data cycle with range slider UI component in ReactJS
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
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) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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 ofreact-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 atconnected-react-router
which is basically just a Redux binding forreact-router
.