предупреждение в ReactJS. Компонент изменяет неконтролируемый вход, подлежащий контролю. Вероятно, это вызвано изменением значения с неопределенного на

#javascript #reactjs

Вопрос:

  • Я изучаю ReactJS и пытаюсь сделать простой конвертер единиц измерения (с официального сайта react) метр в километр
  • Этот код работает и не выдает мне никаких ошибок, но выдает предупреждение в браузере (консоль)
  • Я просто хочу избавиться от этого предупреждения

предупреждение-это:

index.js:1 Предупреждение: Компонент изменяет неконтролируемый вход для управления. Вероятно, это вызвано изменением значения с неопределенного на определенное значение, чего не должно произойти. Решите, использовать ли управляемый или неконтролируемый входной элемент в течение всего срока службы компонента. Дополнительная информация: https://reactjs.org/link/controlled-components

 at input 
at fieldset
at div
at LengthInput (http://localhost:3000/static/js/main.chunk.js:566:5)
at div
at LengthCalculator (http://localhost:3000/static/js/main.chunk.js:609:5)
at Lenght (this is my file name)
at App
 

код выглядит следующим образом:

 import React from "react";

function toKilometer(meter) {
  return meter / 1000;
}

function toMeter(kilometer) {
  return kilometer * 1000;
}

function tryConvert(length, convert) {
  const input = parseFloat(length);
  if (Number.isNaN(input)) {
    return;
  }
  const output = convert(input);
  const rounded = Math.round(output * 1000) / 1000;
  return rounded.toString();
}

const scaleNames = {
  m: "Meter",
  k: "Kilometer",
};

class LengthInput extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
    this.props.onLengthChange(e.target.value);
  }

  render() {
    const length = this.props.length;
    const scale = this.props.scale;
    return (
      <div>
        <fieldset>
          <legend>{scaleNames[scale]}</legend>
          <input value={length} onChange={this.handleChange} />
        </fieldset>
      </div>
    );
  }
}

class LengthCalculator extends React.Component {
  constructor(props) {
    super(props);
    this.state = { length: "", scale: "m" };
    this.handleMeterChange = this.handleMeterChange.bind(this);
    this.handleKilometerChange = this.handleKilometerChange.bind(this);
  }

  handleMeterChange(length) {
    this.setState({ scale: "m", length });
  }

  handleKilometerChange(length) {
    this.setState({ scale: "k", length });
  }

  render() {
    const scale = this.state.scale;
    const length = this.state.length;
    const meter = scale === "k" ? tryConvert(length, toMeter) : length;
    const kilometer = scale === "m" ? tryConvert(length, toKilometer) : length;

    return (
      <>
        <div className="container">
          <LengthInput
            scale="m"
            length={meter}
            onLengthChange={this.handleMeterChange}
          />
          <LengthInput
            scale="k"
            length={kilometer}
            onLengthChange={this.handleKilometerChange}
          />
        </div>
      </>
    );
  }
}

export default function Lenght() {
  return <LengthCalculator />;
}
 

Я прочитал некоторый связанный ответ на stackoverflow, в большинстве из которых говорится, что «мы должны указать значение инициализации в this.state »
, но я делаю это в LengthCalculator

Ответ №1:

я думаю, что это в tryConvert, если длина является пустой строкой, она возвращает неопределенное значение, и вы получаете это предупреждение, если значение не определено, но имеет значение onChange:

 function tryConvert(length, convert) {
  const input = parseFloat(length);
  if (Number.isNaN(input)) {
    return; // this line returns undefined
  }
  const output = convert(input);
  const rounded = Math.round(output * 1000) / 1000;
  return rounded.toString();
}
 

Чтобы избавиться от предупреждения, вы можете сделать значение длиной или, если оно не определено, установить его как пустую строку:

     <fieldset>
      <legend>{scaleNames[scale]}</legend>
      <input value={length || ''} onChange={this.handleChange} />
    </fieldset>
 

Комментарии:

1. Да, это работа… и если я это сделаю return "" , то это тоже сработает. такс