【问题标题】:React - input range with default step as an array of valuesReact - 默认步骤的输入范围作为值数组
【发布时间】:2019-08-21 21:06:43
【问题描述】:

在处理 React 组件时,我尝试设置特定范围的值来确定类型范围输入上的 step。

我能够使用普通 HTML 和 JS 重现所需的行为,即

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();

见代码笔here

但是,当尝试将相同的功能连接到 React 时,无法获得相同的结果。

即

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'));

以上内容不允许我移动幻灯片,也不能一次输出一个步骤。

如何使用 React JS 正确连接它? Ps:随意提供一个示例作为功能组件而不是类。

【问题讨论】:

  • 也许使用 onChange 而不是 onInput
  • 我试过onChange no dice。我想知道如何从我发布到 React 的工作 vanilla JS ex 中重构。
  • 设置输出为一个状态,使用该状态输出。

标签: javascript html reactjs ecmascript-6


【解决方案1】:

在这种情况下,您可以使用state in React 来存储步进输入组件的当前索引,而不是查找输出 DOM 节点并更改其内部 HTML。

这将使您的handleInputChange 功能:

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

React 在它自己的虚拟 DOM 上运行,它将 DOM 节点上的 HTML 属性的名称更改为 React 等效项 -> https://reactjs.org/docs/dom-elements.html。 这意味着您需要在组件中将 oninput 更改为 onInput。

这是你的 React 组件的一个可能的工作版本:

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

【讨论】:

  • 非常感谢您的解释和工作示例。我真的很感激。
【解决方案2】:

这是您的反应范围的工作示例:

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

在这里查看:https://codesandbox.io/s/morning-water-z6fjv?fontsize=14

【讨论】:

  • 非常感谢您提供有效的解决方案和代码框示例。这正是我所追求的。我接受了皮特的回答,因为他之前发布了一点。
猜你喜欢
  • 2012-08-31
  • 2017-11-04
  • 2017-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多