Sai
Sai

Reputation: 81

How to setState of a specific slider?

I'm trying to set the value of a particular slider during onChange event. However, this is resulting in setting the values on all the sliders. I was wondering how to set the state of a particular slider during the onChange event.

This is what I've tried so far (CodeSandbox)

class SimpleSlider extends React.Component {
  state = {
    value: 50
  };

  handleChange = (event, value) => {
    this.setState({ value });
  };

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

    return (
      <div className={classes.root}>
        <Typography id="label">Slider label</Typography>
        <Slider
          id="slider1"
          value={value}
          aria-labelledby="label"
          onChange={this.handleChange}
        />
        <Slider
          id="slider2"
          value={value}
          aria-labelledby="label"
          onChange={this.handleChange}
        />
      </div>
    );
  }
}

Upvotes: 2

Views: 3144

Answers (2)

Tholle
Tholle

Reputation: 112787

You could keep an array in state where every element is the value of a slider, and then pass the index with the value to the onChange handler to update the correct value.

Example

class SimpleSlider extends React.Component {
  state = {
    sliders: [50, 50]
  };

  handleChange = (index, value) => {
    this.setState(previousState => {
      const sliders = [...previousState.sliders];
      sliders[index] = value;
      return { sliders };
    });
  };

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

    return (
      <div className={classes.root}>
        <Typography id="label">Slider label</Typography>
        {this.state.sliders.map((slider, index) => (
          <Slider
            key={index}
            value={slider}
            aria-labelledby="label"
            onChange={(event, value) => this.handleChange(index, value)}
          />
        ))}
      </div>
    );
  }
}

Upvotes: 3

You have two sliders defined inside the same class, which makes them share all atributes such as the state variables. If you move one slider, the other will follow because they share that attribute.

To solve this, create a generic slide class and call it twice, outside that class. Each will have its own properties, therefore its own onChange events.

class GenericSlider extends React.Component {
    state = {
        value: 50
    };

    handleChange = (event, value) => {
        this.setState({ value });
    };    

    render() {
        <Slider
            id={this.props.id}
            value={value}
            aria-labelledby="label"
            onChange={this.handleChange}
        />
    }
}

class SimpleSlider extends React.Component {
  render() {
    const { classes } = this.props;
    const { value } = this.state;

    return (
      <div className={classes.root}>
        <Typography id="label">Slider label</Typography>

        <GenericSlider id="slider1"/>
        <GenericSlider id="slider2"/>
      </div>
    );
  }
}

Upvotes: 0

Related Questions