Правильный способ расчета значений в React.js

Настройка

Итак, в основном у меня есть 3 поля измерений (длина, ширина и высота), которые поддерживаются состоянием. Я хочу сохранить состояние в дюймах, но разрешить пользователю переключать единицы измерения на дисплее по своему желанию. В настоящее время я поддерживаю только дюймы и футы, поэтому у меня есть состояние Dimension_Unit, в котором хранятся текущие отображаемые единицы измерения, и display_dimensions_multiplier, в котором хранится 1,0 для дюймов и 1,0/12,0 для футов (оба находятся в состоянии). У меня все работает именно так, как я хочу, кроме одного.

Проблема

Все значения, которые я пробовал, работали, за исключением случаев, когда вы пытаетесь использовать десятичную дробь. По сути, в фоновом режиме он запускает множитель, чтобы сохранить состояние при изменении, а затем умножает обратно значение для поля, которое в основном стирает замыкающий . когда вы печатаете, скажем, вы пытались ввести 4.5, то, что вы на самом деле получили бы в поле, когда вы набрали, равно 45. Но если вы наберете 45, а затем переместите курсор между 4 и 5, добавьте . у вас получится 4,5...

Моя идея

Я думал о том, как решить эту проблему: в основном иметь переменную состояния для display_length, а затем иметь состояние обычной длины, а затем иметь display_length неизменным, если только они не изменят единицы измерения и не рассчитывают и не сохраняют длину при изменении, а затем просто сохраняют это... и то же самое для высоты и ширины... но это кажется очень нереактивным, так как же реактивный способ сделать это? Или это все?

С удовольствием опубликую пример кода, если это необходимо, но для любого компонента есть хороший кусок кода, так что... да... надеюсь, достаточно только объяснения.

Редактировать1

Базовый перед скрипкой: до

Это моя идея, которая меня интересует: после

Основное отличие заключается в следующем:

_handleChange: function(ev){
  ev.stopPropagation()
  ev.preventDefault()
  var key = ev.target.name;
  var value = ev.target.value;
  var indims = this.state.input_dimensions;
  indims[key] = value;
  this.setState({input_dimensions: indims});
  value = (value / this.state.display_dimensions_multiplier);
  var dims = this.state.dimensions;
  dims[key] = value;
  this.setState({dimensions: dims});
},

person Matthew Clark    schedule 09.04.2016    source источник
comment
Можете ли вы заставить что-то работать в скрипке? это помогло бы, я понимаю, в чем ваша проблема, но не уверен в предложенном вами решении. PS Google 'React Base fiddle' для хорошей отправной точки   -  person omarjmh    schedule 09.04.2016
comment
Потребуется немного времени, чтобы раздеться и сделать до и после, но я подниму его и опубликую, как только смогу.   -  person Matthew Clark    schedule 09.04.2016
comment
Нет необходимости, если ответ ниже вас устраивает!   -  person omarjmh    schedule 09.04.2016
comment
Добавил оба. Интересно услышать мысли! Спасибо!   -  person Matthew Clark    schedule 09.04.2016


Ответы (1)


Я думаю, что ваше решение является правильной идеей. Несколько похожих идей:

  • Обновляйте сохраненное значение только после фиксации ввода (например, onBlur вместо onChange). Вы можете применить общую проверку ввода в реальном времени, чтобы убедиться, что это действительное число.
  • Как вы говорите, используйте отдельное состояние «отображения» (я бы назвал это «состоянием ввода»), и когда компонент обновляется новым сохраненным значением, обновляйте состояние ввода только в том случае, если оно отличается (при преобразовании в те же единицы). Таким образом, вам не нужно упорствовать или беспокоиться о «состоянии ввода» вне компонентов ввода.
  • Когда вход имеет фокус, не обновляйте состояние ввода при изменении сохраненного значения. Когда вход не имеет фокуса или размыт, обновите состояние ввода до сохраненного значения.

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

person Aaron Beall    schedule 09.04.2016
comment
Спасибо за Ваш ответ! Я добавил пару скрипок. Пожалуйста, дайте мне знать, что вы думаете! - person Matthew Clark; 09.04.2016