Как обновить одно поле в соответствии с другим в реакции?

У меня есть два поля ввода для интерфейса обмена. Цель состоит в том, чтобы обновить другой в соответствии с вводом (на основе обменного курса). Пользователь может ввести любой из них.

Проблема: если пользователи вводят 5 и получают 500 в другом, а затем удаляют два 0 из 500, он не сможет получить обновление состояния и вернуть 0,05 в другом.

Чтобы было легче визуализировать, у меня это в кодыпесочница. Ниже приведен код.

import "./styles.css";
import React from "react";

export default function App() {
  const rate = 100;
  const [token, setToken] = React.useState();
  const [eth, setEth] = React.useState();

  console.info("token", token);
  console.info("eth", eth);

  return (
    <div className = "App">
      <h1>1 eth = 100 token</h1>
      <h2>goal: change one input, the other updates automatically</h2>
      <input
        placeholder = "eth"
        value = {eth}
        onChange = {(e) => {
          let eth_input = e.target.value;
          console.info(eth_input);
          setToken(eth_input * rate);
        }}
      />
      <input
        placeholder = "token"
        value = {token}
        onChange = {(e) => {
          let token_input = e.target.value;
          console.info(token_input);
          setEth(token_input / rate);
        }}
      />
    </div>
  );
}

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
32
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

  <input
    placeholder = "eth"
    value = {eth}
    onChange = {(e) => {
      let eth_input = e.target.value;
      console.info(eth_input);
      setEth(eth_input)
      setToken(eth_input * rate);
    }}
  />
  <input
    placeholder = "token"
    value = {token}
    onChange = {(e) => {
      let token_input = e.target.value;
      console.info(token_input);
      setToken(token_input)
      setEth(token_input / rate);
    }}
  />
Ответ принят как подходящий

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

Это происходит из-за того, что, хотя ваши входные данные получали свое значение из состояния, их обработчики изменений не обновляли то же самое состояние входным значением. Вы обновляли состояние входа Другие, но не их самих.

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

import "./styles.css";
import React from "react";

export default function App() {
  const rate = 100;
  const [token, setToken] = React.useState();
  const [eth, setEth] = React.useState();

  console.info("token", token);
  console.info("eth", eth);

  return (
    <div className = "App">
      <h1>1 eth = 100 token</h1>
      <h2>goal: change one input, the other updates automatically</h2>
      <input
        placeholder = "eth"
        value = {eth}
        onChange = {(e) => {
          let eth_input = e.target.value;
          console.info(eth_input);
          setEth(eth_input); // <-- add this
          setToken(eth_input * rate);
        }}
      />
      <input
        placeholder = "token"
        value = {token}
        onChange = {(e) => {
          let token_input = e.target.value;
          console.info(token_input);
          setToken(token_input); // <-- and this
          setEth(token_input / rate);
        }}
      />
    </div>
  ):
}

спасибо! это решает проблему. тем не менее, у него все еще есть ошибка неконтролируемого ввода. Безопасно ли игнорировать или есть что-то, чтобы это исправить?

hohololoo 19.03.2022 00:41

О, ты прав. На самом деле это просто потому, что ваши значения состояния начинаются как undefined. Если вы измените useState() на useState(""), это исчезнет и все еще будет работать так, как вы хотите.

Robin Zigmond 19.03.2022 01:01

Другие вопросы по теме