Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React JS range slider - using an array for the value?

I'm wondering how you'd go about getting the value of an index in an array using an input[type="range"] in React, similar to this example?

What I'm trying to do is this: pass in a range of values and be able to print out those values by using the index of the array.

As you'll see from the example code below, I am initially rendering the value I want (in this case, 'Apples') but then when I use the slide it then starts rendering the index of the array, instead of the values.

Here's what I've got so far:

class RangeSlider extends React.Component {
  // constructor
  constructor(props) {
    super(props);
    this.state = {
      value: props.value[0]
    };
  }

  handleChange(event, index) {
    const { value } = this.state;
    this.setState({ value: event.target.value});
  }

  render() {
    const { value } = this.state;
    const { label } = this.props;

    return (
      <div className="mb4">
        <label className="f4 mt0">
          {label} <b className="fw7 pl1">{value}</b>
        </label>
        <input
          className="w-100 appearance-none bg-transparent range-slider-thumb-custom"
          type="range"
          min={0}
          max={this.props.value.length - 1}
          step={1}
          value={value}
          onChange={this.handleChange.bind(this)}
        />
      </div>
    );
  }

}

window.onload = () => {
  ReactDOM.render(
    <RangeSlider 
      label={"I would like some "} 
      value={["Apples", "Oranges", "Pears"]} />, 
    document.getElementById("main"));
};

Link to a Codepen.

like image 381
A7DC Avatar asked Oct 18 '22 07:10

A7DC


1 Answers

The only problem you were having is that on initial load, your state object was set to access the value in the array correctly. However, everytime the handleChange method fires, it overwrites the state with just an integer, and thus does not do what you are expecting.

If you instead just set the "value" property in your state object to a default value of "0", you can just track the index, and change one more line in your code, and it should work just fine.

First change your state to look like this:

this.state = {
  value: 0
};

Next, change to this inside your jsx body:

{label} <b className="fw7 pl1">{this.props.value[value]}</b>

This way, you are always going to print out a value, and not an integer to the screen. I think this results in you having to add far less code.

Working Codepen.

like image 90
Dan Zuzevich Avatar answered Oct 27 '22 01:10

Dan Zuzevich