web-dev-qa-db-de.com

JSX React HTML5-Eingaberegler funktioniert nicht

Ich verwende React.JS für einen Build und baue einen Schieberegler für die Bereichseingabe mit zwei Auswahlmöglichkeiten für eine Komponente.

das ist mein Code:

<input id="typeinp" type="range" min="0" max="5" value="3" step="1"/>

Wenn ich es in meine clientseitige Komponente zum Rendern platziere und versuche, es umzuschalten, wird es überhaupt nicht verschoben. Wenn ich es mit einem JS/PHP-Build teste, funktioniert es gut.

Warum funktioniert das in JSX/React.JS nicht und was wäre eine Umgehungsmöglichkeit?

Vielen Dank!

11
CodeFromthe510

Benutzerinteraktionen haben keine Auswirkungen, da ein <input> mit value prop als Controlled betrachtet wird. Dies bedeutet, dass der angezeigte Wert vollständig von der Funktion render gesteuert wird. Um den Eingabewert tatsächlich zu aktualisieren, sollten Sie das Ereignis onChange verwenden. Beispiel:

getInitialState: function() {
  return {value: 3};
},
handleChange: function(event) {
  this.setState({value: event.target.value});
},
render: function() {
  return (
    <input 
      id="typeinp" 
      type="range" 
      min="0" max="5" 
      value={this.state.value} 
      onChange={this.handleChange}
      step="1"/>
  );
}

Sie können auch defaultValue anstelle von value verwenden. In diesem Fall wird <input> als unkontrolliert betrachtet, und alle Benutzerinteraktionen werden sofort vom Element selbst wiedergegeben, ohne die render-Funktion Ihrer Komponente aufzurufen.

Mehr dazu in offiziellen Dokumentation

28
xCrZx

Ich denke, vorherige Antworten haben Ihr Problem gelöst. Ich würde jedoch sagen, dass die Lösung keine React-Zustände beinhalten muss.

Der einzige Grund hinter Ihrem eingefrorenen Eingabeschieberegler ist, dass Sie den Wert auf 3 hartcodiert haben, wie @Colin Whitmarsh vorschlägt.

Das funktioniert einfach:

<input id="typeinp" type="range" min="0" max="5" defaultValue="3" step="1"/>

Nun brauchen Sie wahrscheinlich die Ausgabe, um etwas zu tun. Sie können onChange={this.handleChange} als @xCrZx-Status in seiner Antwort verwenden. In handleChange müssen Sie jedoch nicht unbedingt Ihren Status aktualisieren. Abhängig von Ihrer Logik können Sie vermeiden, die Komplexität Ihres Zustands zu erhöhen, und Ihre Logik einfach in handleChange codieren.

Wenn Sie es vermeiden, den Status zu aktualisieren, werden Sie wahrscheinlich einige Renders speichern, und Ihre Leistung wird verbessert.

3
Daniel Reina

Hier finden Sie eine Lösung zum Erstellen mehrerer Schieberegler oder sogar eines einzelnen Schiebereglers mit übergebenen Ereignishandlern Sie können einfach die HTML-Eingabe des Typs Range rc-slider und Reaktineingabebereich verwenden. event handleronChange oder onAfterChange nicht gesendet, da sie den Wert des Schiebereglers implizit senden, daher können wir die Form der Schieberegler nicht handhaben oder sie nicht spontan erstellen. 

jsfiddle schnipsel

Für weitere Informationen können wir HTML-Eingabebereich prüfen und CSS von CSS-Tricks

class SlidersExample extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      slidersLabels: ["A", "B", "C", "D"],
      sumOfCustomWeights: 0,
      slidersWeights: []
    };
  }
  componentDidMount() {
    const slidersLabels = this.state.slidersLabels;
    const slidersWeights = [];
    for (var i = 0; i < slidersLabels.length; ++i)
      slidersWeights[slidersLabels[i]] = 0;
    this.setState({ slidersWeights });
  }

  render() {
    return (
      <div>
        {this.generateSliders()}
        <span> Total Weights: {this.state.sumOfCustomWeights} </span>
      </div>
    );
  }
  generateSliders() {
    const slidersLabels = this.state.slidersLabels;
    var sliders = [];
    for (var i = 0; i < slidersLabels.length; ++i) {
      sliders.Push(
        <div style={{ marginTop: "20px", marginBottom: "20px" }}>
          <span style={{ fontSize: "16px", marginBottom: "6px" }}>
            {" "}
            {slidersLabels[i]} ({this.state.slidersWeights[slidersLabels[i]]})%
          </span>
          <input
            id={slidersLabels[i]}
            type="range"
            defaultValue="0"
            min="0"
            max="100"
            className="slider"
            onChange={this.handleSliderChange.bind(this)}
            step="1"
          />
        </div>
      );
    }
     return sliders;
  }
  handleSliderChange(event) {
    //console.log(event.target.value, " ", event.target.id);
    var id = event.target.id;
    var value = event.target.value;
    const slidersWeights = this.state.slidersWeights;
    slidersWeights[id] = parseInt(value);
    var sumOfCustomWeights = 0;
    const slidersLabels = this.state.slidersLabels;
    for (var i = 0; i < slidersLabels.length; i++)
      sumOfCustomWeights += slidersWeights[slidersLabels[i]];
    this.setState({ slidersWeights, sumOfCustomWeights });
  }
}

ReactDOM.render(<SlidersExample />, document.querySelector("#app"));
input[type=range] {
  -webkit-appearance: none;
  margin: 18px 0;
  width: 100%;
}
input[type=range]:focus {
  outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
  width: 100%;
  height: 8.4px;
  cursor: pointer;
  animate: 0.2s;
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
  background: #3071a9;
  border-radius: 1.3px;
  border: 0.2px solid #010101;
}
input[type=range]::-webkit-slider-thumb {
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
  border: 1px solid #000000;
  height: 36px;
  width: 16px;
  border-radius: 3px;
  background: #ffffff;
  cursor: pointer;
  -webkit-appearance: none;
  margin-top: -14px;
}
input[type=range]:focus::-webkit-slider-runnable-track {
  background: #367ebd;
}
input[type=range]::-moz-range-track {
  width: 100%;
  height: 8.4px;
  cursor: pointer;
  animate: 0.2s;
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
  background: #3071a9;
  border-radius: 1.3px;
  border: 0.2px solid #010101;
}
input[type=range]::-moz-range-thumb {
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
  border: 1px solid #000000;
  height: 36px;
  width: 16px;
  border-radius: 3px;
  background: #ffffff;
  cursor: pointer;
}
input[type=range]::-ms-track {
  width: 100%;
  height: 8.4px;
  cursor: pointer;
  animate: 0.2s;
  background: transparent;
  border-color: transparent;
  border-width: 16px 0;
  color: transparent;
}
input[type=range]::-ms-fill-lower {
  background: #2a6495;
  border: 0.2px solid #010101;
  border-radius: 2.6px;
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
}
input[type=range]::-ms-fill-upper {
  background: #3071a9;
  border: 0.2px solid #010101;
  border-radius: 2.6px;
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
}
input[type=range]::-ms-thumb {
  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
  border: 1px solid #000000;
  height: 36px;
  width: 16px;
  border-radius: 3px;
  background: #ffffff;
  cursor: pointer;
}
input[type=range]:focus::-ms-fill-lower {
  background: #3071a9;
}
input[type=range]:focus::-ms-fill-upper {
  background: #367ebd;
}

#app{
  margin-right: 100px;
  margin-left: 100px;
  margin-bottom: 100px;
  }
<!DOCTYPE html>
<html>
<body>


<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"> </div>
</body>
</html>

Diese Lösung funktioniert perfekt mit mir;)

CodeSandbox verwenden

0
Abdallah Okasha

Versuche dies:

onInput() {
    var input = document.getElementById("typeinp");
    var currentVal = input.value;
    this.setState({
      value: currentVal
    })
}

<input id="typeinp" type="range" min="0" max="5" step="1" defaultValue="3" onInput={this.onInput.bind(this)}/>

Ich schlage vor, value = "3" in defaultValue = "3" zu ändern, andernfalls denke ich, dass der Wert hart in "3" codiert ist und möglicherweise nur schwer oder gar nicht geändert werden kann. Die Funktion onInput sucht den Wert und fügt ihn dem Status hinzu, sodass die Daten an eine andere Komponente oder Funktion übergeben werden können. Es gibt wahrscheinlich eine elegantere Lösung für Ihr Problem, aber die obigen Ausführungen sollten funktionieren. 

0
Colin Whitmarsh