Alex Bollbach
Alex Bollbach

Reputation: 4570

Trying to get a React controlled input to have a default value

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>
            )
    }
}

Upvotes: 7

Views: 5206

Answers (1)

Noumenon
Noumenon

Reputation: 6412

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}/>

Upvotes: 2

Related Questions