6
votes

I have a component Slider which consists only of a <div> for a title of some parameter, and an input slider to control its value. It takes props for the title and the current value of that property to initialize the position of the slider knob. I have read about React's controlled components, and although I think I understand the basic concepts, I am having trouble getting this input slider to initialize to this.props.initialValue. If I try to give the <input> a default value with, <input defaultValue={this.props.initialValue}..., I get:

bundle.js:357 Warning: Slider contains an input of type range with both value and defaultValue props. Input elements must be either controlled or uncontrolled (specify either the value prop, or the defaultValue prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props. More info: Link

Which is what brought me to reading about controlled components in the first place. I think I understand how defaultValue relates to the input element storing state itself which is what controlled components are entirely not about.

So then my question is HOW to initialize the slider to a value?? Google searches reveal little, except to have the following: <input value={this.state.value}... And then since in my constructor, I'm initializing state.value to this.props.initialValue, I would think the component's first render would give me a slider with that value. But it doesn't.

Here is my current component code:

class Slider extends React.Component {

    constructor(props) {
        super(props)

        this.state = {
            value: props.initialValue
        } 
        this.sliderChanged = this.sliderChanged.bind(this)
    }

    sliderChanged(e) {
        this.setState( { value: e.target.value} );
        this.props.valueChanged(e.target.value)
    }

    render() {

        const containerStyle = {
            display: "grid",
            gridTemplateRows: "2fr 3fr",
            textAlign: "center",
        }

        const titleStyle = {
            backgroundColor: "purple",
            color: "white",
            textAlign: "center",
        }

        const sliderStyle = {
            backgroundColor: "orange",
        }

        console.log(this.state)


        return (
            <div style={containerStyle}>
            <div style={titleStyle}>{this.props.title}</div>
            <div style={sliderStyle}>
            <input 
            type="range" 
            value={this.state.value} 
            onChange={this.sliderChanged} />
            </div>
            </div>
            )
    }
}
1
Your code should work. Did you confirm you receive the expected props under constructor? Also confirm that the given value is in the bounds of the range min and max, I believe the default range is 0-100 works in this js fiddle: jsfiddle.net/kz2gq2qc/2 - Gershon Papi
what's the value of props.initialValue? - Edgar Henriquez
i was using a range of 0-1. so the slider was being set but undetectably by my eyes. did not know the range was of 100. should i delete the question? - Alex Bollbach

1 Answers

1
votes

React blog recommends using the key prop to force the input to rerender, so you can re-initialize the state with new props.

<Slider key={initialValue}/>