React onChange не работает для ввода внутри функционального компонента

Я делал это миллион раз, и никогда не было этой проблемы, и я не знаю, что делаю не так. У меня есть простое поле ввода и крючок useState из amount и setAmount, и я использую функцию handleChange для обновления этого, но функция handleChange не запускается

const CustomAmount = () => {
  const [amount, setAmount] = useState(1);

  const handleChange = (e) => {
    console.log(e); // This is not working either

    setAmount(e.target.value);
  };
  return (
    <div className="custom-amount-container">
      <h4>Enter your desired amount</h4>
      <input
        type="number"
        name="custom-amount"
        data-test="custom-amount-input"
        value={amount}
        onChange={handleChange}
      />
    </div>
  );
};

Я попытался поместить его в опору onChange напрямую, но все равно не повезло, а также обычно, если функция onChange не работает, она не меняет значение, но в этом случае значение изменяется внутри поля ввода

Также я использую этот компонент внутри sweetalert модального

 const customAmountModal = () => {
    return swal(<CustomAmount />);
  };

person Sulman Azhar    schedule 25.02.2021    source источник
comment
вы имеете в виду e.target.value (без s)?   -  person azium    schedule 25.02.2021
comment
Ой, извините за то, что он не работает в любом случае, и это опечатка, когда я копировал, плохо отредактировал его   -  person Sulman Azhar    schedule 25.02.2021
comment
он работает codeandbox.io/s/quirky-gagarin-r6xjv ? file = / src / App.js у вас возникают ошибки? это твой точный код?   -  person azium    schedule 25.02.2021
comment
@SulmanAzhar Я не использовал sweetalert, но вы правильно передаете компонент? Возможная ошибка могла быть там.   -  person Lakshya Thakur    schedule 25.02.2021
comment
Это мой точный код, и поэтому он так запутан, как будто это базовые вещи, и я знаю, что не делаю ничего плохого и не ошибаюсь. Может это из-за sweetalert?   -  person Sulman Azhar    schedule 25.02.2021
comment
да, где написано, что ты умеешь swal(<Component />)? в документации говорится, что вы передаете объект sweetalert.js.org/guides   -  person azium    schedule 25.02.2021
comment
i.imgur.com/sCR3WO4.png Я увидел эту часть и подумал, почему я не имею в виду jsx так что он должен работать технически. Или я что-то упускаю? Также это codeandbox, пожалуйста, посмотрите codesandbox.io/ s / nice-tree-1lyg3? file = / src / App.js.   -  person Sulman Azhar    schedule 25.02.2021


Ответы (4)


Я пытался отладить причину, по которой обработчики событий не вызываются для компонента, заключенного внутри swal, но не смог. Поэтому, согласно моему ограниченному пониманию, Синтетические события React не запускаются для таких компонентов, но если вы используете Собственные события DOM, вы можете достичь тех же функций, например: -

import { useEffect, useRef, useState } from "react";
import swal from "@sweetalert/with-react";
import "./styles.css";

const CustomAmount = () => {
  const [amount, setAmount] = useState(1);
  const inputRef = useRef(null);
  const handleChange = (e) => {
    console.log(e.target.value);
    setAmount(e.target.value);
  };

  console.log("render", amount);

  useEffect(() => {
    inputRef.current.addEventListener("input", handleChange);
  }, []);
  return (
    <div className="custom-amount-container">
      <h4>Enter your desired amount</h4>

      <input
        type="number"
        name="custom-amount"
        data-test="custom-amount-input"
        value={amount}
        ref={inputRef}
      />
    </div>
  );
};

export default function App() {
  const customAmountModal = () => {
    return swal(<CustomAmount />);
  };
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <button onClick={customAmountModal}>Click me</button>
    </div>
  );
}

Вот ссылка на codeandbox - https://codesandbox.io/s/mystifying-jang-jrgex?file=/src/App.js

По-прежнему хотелось бы знать, почему метод React не работает. На самом деле не работал с swal, поэтому не знал о сценариях использования, для которых он создан.

person Lakshya Thakur    schedule 25.02.2021
comment
Вы самый лучший человек. хотя он делает именно то, что мне нужно, я получаю это предупреждение, потому что для ввода нет метода onChange - person Sulman Azhar; 25.02.2021
comment
Не беспокойся, чувак. И да, вы получите это предупреждение, поскольку сейчас вы находитесь вне потока событий React, поэтому оно говорит вам, что value может никогда не измениться, поэтому вместо этого выберите defaultValue или сделайте его только для чтения. Честно говоря, можно использовать библиотеку, которая позволяет вам делать что-то гораздо более простым React способом, или проверить, есть ли более новая версия, которая может вам помочь. То, что я дал, - это просто обходной путь. Уже проголосовали за ваш вопрос, так что, возможно, мы получим что-то получше. - person Lakshya Thakur; 25.02.2021
comment
Ты прав. Я использую swal для работы с модальным типом в этой ситуации, поэтому я думаю, что могу использовать любую другую модальную библиотеку или создать свою собственную. В любом случае спасибо за помощь, это было информативно - person Sulman Azhar; 25.02.2021

В настоящее время это известная проблема с swal and react 17: https://github.com/t4t5/sweetalert/issues/950

Автор в курсе и говорит, что скоро выпустит обновления.

Не стесняйтесь голосовать за проблему / следить за обновлением по этому поводу.

person silicakes    schedule 25.02.2021

Это потому, что объекты SyntheticEvent объединены в пул. Это означает, что объект SyntheticEvent будет повторно использован, и все свойства будут обнулены после вызова обработчика событий.

Теперь вы повторно используете объект события, сначала это функция console.log, а затем в setState.

См. https://reactjs.org/docs/legacy-event-pooling.html

person QurcoJr    schedule 25.02.2021

Вы также можете просто сделать

onChange={e => setAmount(e.target.value)
person chip    schedule 25.02.2021
comment
Нет, это не сработает, так как это то же самое, что и onChange = {handleChange}, и да, я пробовал, в основном события не запускаются - person Sulman Azhar; 25.02.2021