最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React - input range with default step as an array of values - Stack Overflow

programmeradmin4浏览0评论

While working on a React Component, I'm trying to set a specific range of values to determine the step on a type range input.

I'm able to reproduce the desired behavior with vanilla HTML and JS i.e.

HTML

<!-- custom step range -->
<div class="step">
  <input id="input" type="range" min="0" value="0" max="4" step="1" list="tick-list">
  <datalist id="tick-list">
    <option>0</option>
    <option>1</option>
    <option>2</option>
    <option>3</option>
    <option>4</option>
</datalist>
  <span id="output"></span>

</div>

JS

var values = [10,25,50, 75, 100];

var input = document.getElementById('input'),
   output = document.getElementById('output');
input.oninput = function(){
    output.innerHTML = values[this.value];
};
input.oninput();

see codepen here

However, not able to achieve the same results when trying to wire this same functionality to React.

i.e.

class App extends Component {
  constructor() {
    super();
    this.state = {
      values : [10, 25, 50, 75, 100]
    };
  }

  handleInputChange = () => {
    const input = document.querySelector('input'),
    const output = document.getElementById('output');
    output = this.state.values;
  };


  render() {
    return (
      <div>
        <input
          oninput={this.handleInputChange()}
          type="range"
          min="0"
          value="0"
          max="4"
          step="1"
          list="tick-list" />
        <datalist id="tick-list">
          <option value="0" />
          <option value="1" />
          <option value="2" />
          <option value="3" />
          <option value="4" />
        </datalist>
        <span id="output">{this.state.values}</span>
      </div>
    );
  }
}

render(<App />, document.getElementById('root'));

The above doesn't let me move the slide nor outputs the steps one at time.

How could I wire this properly using React JS? Ps: Feel free to provide an example as a functional ponent rather than a class.

While working on a React Component, I'm trying to set a specific range of values to determine the step on a type range input.

I'm able to reproduce the desired behavior with vanilla HTML and JS i.e.

HTML

<!-- custom step range -->
<div class="step">
  <input id="input" type="range" min="0" value="0" max="4" step="1" list="tick-list">
  <datalist id="tick-list">
    <option>0</option>
    <option>1</option>
    <option>2</option>
    <option>3</option>
    <option>4</option>
</datalist>
  <span id="output"></span>

</div>

JS

var values = [10,25,50, 75, 100];

var input = document.getElementById('input'),
   output = document.getElementById('output');
input.oninput = function(){
    output.innerHTML = values[this.value];
};
input.oninput();

see codepen here

However, not able to achieve the same results when trying to wire this same functionality to React.

i.e.

class App extends Component {
  constructor() {
    super();
    this.state = {
      values : [10, 25, 50, 75, 100]
    };
  }

  handleInputChange = () => {
    const input = document.querySelector('input'),
    const output = document.getElementById('output');
    output = this.state.values;
  };


  render() {
    return (
      <div>
        <input
          oninput={this.handleInputChange()}
          type="range"
          min="0"
          value="0"
          max="4"
          step="1"
          list="tick-list" />
        <datalist id="tick-list">
          <option value="0" />
          <option value="1" />
          <option value="2" />
          <option value="3" />
          <option value="4" />
        </datalist>
        <span id="output">{this.state.values}</span>
      </div>
    );
  }
}

render(<App />, document.getElementById('root'));

The above doesn't let me move the slide nor outputs the steps one at time.

How could I wire this properly using React JS? Ps: Feel free to provide an example as a functional ponent rather than a class.

Share Improve this question edited Aug 21, 2019 at 21:27 Null isTrue asked Aug 21, 2019 at 21:06 Null isTrueNull isTrue 1,9368 gold badges31 silver badges50 bronze badges 4
  • Try this method: stackoverflow./questions/45167565/… – inertia Commented Aug 21, 2019 at 21:12
  • Perhaps using onChange instead of onInput – inertia Commented Aug 21, 2019 at 21:13
  • I tried onChange no dice. I'm wondering how to refactor from the working vanilla JS ex I posted to React. – Null isTrue Commented Aug 21, 2019 at 21:16
  • Set the output to a state and output using the state. – inertia Commented Aug 21, 2019 at 21:20
Add a ment  | 

2 Answers 2

Reset to default 2

In this case you can make use of state in React to store the current index of your stepped input ponent, rather than finding the output DOM node and changing it's inner HTML.

Which would makes your handleInputChange function:

handleInputChange = e => {
    this.setState({ currentStep: e.currentTarget.value });
  };

React operates on it's own virtual DOM, it changes the names of the HTML attributes on the DOM nodes to a React equivalent -> https://reactjs/docs/dom-elements.html. Which means you'll need to change oninput to onInput in your ponent.

Here is one possible working version of your React ponent:

import React from "react";
import { render } from "react-dom";

class App extends React.Component {
  values = [10, 25, 50, 75, 100];

  constructor(props) {
    super(props);
    this.state = {
      currentStepIndex: 0
    };
  }

  handleInputChange = e => {
    this.setState({ currentStepIndex: e.currentTarget.value });
  };

  render() {
    return (
      <div>
        <input
          onInput={this.handleInputChange}
          type="range"
          min="0"
          value={this.state.currentStepIndex}
          max="4"
          step="1"
          list="tick-list"
        />
        <datalist id="tick-list">
          <option>0</option>
          <option>1</option>
          <option>2</option>
          <option>3</option>
          <option>4</option>
        </datalist>
        <span id="output">{this.values[this.state.currentStepIndex]}</span>
      </div>
    );
  }
}

render(<App />, document.getElementById("root"));

code sandbox

Here is a working example for your react range:

class App extends Component {
  constructor() {
    super();
    this.state = {
      rangeValues: [10, 25, 50, 75, 100],
      currentRangeValue: 0
    };

    this.handleInputChange = this.handleInputChange.bind(this);
  }

  handleInputChange = (e) => {
    this.setState({ currentRangeValue: e.target.value });
  };


  render() {
    const { rangeValues, currentRangeValue } = this.state
    return (
      <div>
        <input
          onChange={this.handleInputChange}
          type={"range"}
          min={0}
          defaultValue={0}
          max={4}
          step={1}
          list={"tick-list"} />
        <datalist id="tick-list">
          <option>0</option>
          <option>1</option>
          <option>2</option>
          <option>3</option>
          <option>4</option>
        </datalist>
        <span id="output">{rangeValues[currentRangeValue]}</span>
      </div>
    );
  }
}

Check it here: https://codesandbox.io/s/morning-water-z6fjv?fontsize=14

发布评论

评论列表(0)

  1. 暂无评论