Slider: Cant move the slider if property value is set

Created on 23 Nov 2017  路  12Comments  路  Source: react-component/slider

Hi,
I use the current stable version of rc-slider and I have noticed that you cant slide anymore if you set the value property. You could use defaultValue instead (moving works with it). The problem is that I want to set the value programmatically and still be able to change the value by sliding.

Is there a fast fix?

EDIT:
Notied that it works if you use onChange instead OnAfterChange. I would like to set the value after a mousedrop. So I do not need to fire events if the value is changed by sliding but only after a mousdrop or a blur action.

Most helpful comment

Something like this

import React from 'react'
import Slider from 'rc-slider'

export class Filter extends React.Component {
    constructor(props) {
        super(props)
        const { value } = this.props
        this.state = { value }
    }
    setValue(e) {
        this.setState({ value: e })
    }
    update() {
        this.props.update(this.state)
    }
    render() {
        return <Slider value={this.state.value} onChange={this.setValue.bind(this)} onAfterChange={this.update.bind(this)} />
    }
}

All 12 comments

I'm exactly in the same case. I'm using Redux & ReduxForm, so I'm using this Slider as a controlled input (the onAfterChange is sent to ReduxForm, and then the value is set from ReduxForm too). If I use onChange, the performance drop is important, and if I debounce the value sent to ReduxForm, the Slider is only updated after the onAfterChange. I really can't use it on production right now.

I did a workaround. I built a component that use setState for the value and a dispatch at onAfterChange. So the moving works and the final value after drop is forwarded via dispatch. I guess thats the "react" way to do.

I'm experiencing the same issue when attempting to set the value programmatically. @rudolfschmidt Would it be possible to explain your approach a bit more?

Something like this

import React from 'react'
import Slider from 'rc-slider'

export class Filter extends React.Component {
    constructor(props) {
        super(props)
        const { value } = this.props
        this.state = { value }
    }
    setValue(e) {
        this.setState({ value: e })
    }
    update() {
        this.props.update(this.state)
    }
    render() {
        return <Slider value={this.state.value} onChange={this.setValue.bind(this)} onAfterChange={this.update.bind(this)} />
    }
}

Thanks, @rudolfschmidt.

import React from 'react';
import Slider, {Range} from 'rc-slider';
import 'rc-slider/assets/index.css';

const RangeWithTooltip = Slider.createSliderWithTooltip(Range);

class ReduxFormRangeSlider extends React.Component {
    constructor(props) {
        super(props)
        this.state = { value: this.props.input.value }
    }
    componentDidUpdate(prevProps) {
        if(prevProps.input.value !== this.props.input.value) {
            this.setState({value: this.props.input.value})
        }
    }
    render() {
        return <RangeWithTooltip value={this.state.value}
                                 onChange={newVal => this.setState({ value: newVal })}
                                 onAfterChange={newVal => this.props.input.onChange(newVal)}
                                 {...this.props}
        />
    }

}

export default ReduxFormRangeSlider;

Thanks for sharing @rudolfschmidt.

Hi @rudolfschmidt
If i supply the same functions to both onChange and onAfterChange, it should move the slider right? I'm currently not able to move the slider. i'm doing something on the lines of this ----

```import React from 'react'
import Slider from 'rc-slider'

export class Filter extends React.Component {
constructor(props) {
super(props)
const { value } = this.props
this.state = { value }
this.setValue = this.setValue.bind(this);
}
setValue(e) {
this.setState({ value: e })
}
render() {
return
}
}

590 I am facing this problem too. Can anyone help?

@premkiran7 can you post a minimal reproducible example of your code?

I have added a code sandbox link in #590

I did a workaround. I built a component that use setState for the value and a dispatch at onAfterChange. So the moving works and the final value after drop is forwarded via dispatch. I guess thats the "react" way to do.

This seems like bad behavior as the reason for using a slider and not a drop down is to make changes live as the user slides the input. Its seems like a big issue that the component can not be used as a controlled component that if value is determined through a controlled component the slider/range will not slide.

  // Range component disables interaction if value is set.
  // Ugly hack is to remove the value prop after the component
  // has rendered sliders into place.

  const [rangeProps, setRangeProps] = useState({}); 
  useEffect(() => {
    setRangeProps({value: [...range]});
    window.requestAnimationFrame(() => {
      setRangeProps({});
    });
  }, [range])

  return <Range {...rangeProps} />
Was this page helpful?
0 / 5 - 0 ratings

Related issues

Gautierrr picture Gautierrr  路  7Comments

OlivierCo picture OlivierCo  路  5Comments

Bernabe-Felix picture Bernabe-Felix  路  3Comments

johnb8005 picture johnb8005  路  6Comments

ka7eh picture ka7eh  路  6Comments