Это выражение не вызывается при разрушении массива хуков React в TypeScript - PullRequest
0 голосов
/ 10 апреля 2020

В моем компоненте React TS у меня есть несколько полей, приведенный ниже пример, который проверяет заданное условие c, и, если оно не выполняется, задайте для указанного поля ошибки c значение true, чтобы оно отображалось и компонент DOM (и, следовательно, не отправлять) Однако, когда у меня есть код ниже, он expression not callable вызывает функцию setErr.

const App = () => {
  const [name, setName] = React.useState("");
  const [email, setEmail] = React.useState("");
  const [nameError, setNameError] = React.useState(false);
  const [emailError, setEmailError] = React.useState(false);
  return (
    <div className="App">
      <input
        type="text"
        value={name}
        style={{
          border: `1 px solid ${nameError ? "red" : "black"}`
        }}
        onChange={e => {
          setName(e.target.value);
        }}
      />
      <input
        type="text"
        value={email}
        onChange={e => {
          setEmail(e.target.value);
        }}
        style={{
          border: `1 px solid ${emailError ? "red" : "black"}`
        }}
      />
      <button
        onClick={() => {
          const errors = [
            [setNameError, name.length],
            [setEmailError, email.length]
          ];

          let canSubmit = true;
          errors.forEach(validation => {
            const [setErr, condition] = validation;
            console.log(!condition);
            if (!condition) {
              canSubmit = false;
              setErr(true); // <---- ERROR HERE
            }
          });

          if (canSubmit) { /* submit the form */ } 
        }}
      >
        submit
      </button>
    </div>
  );
};

Это только ошибки в TypeScript, так как он отлично работает в vanilla / JSX. И не компилируется в некоторых системах сборки.

Полная ошибка:

This expression is not callable.
  Not all constituents of type 'string | number | boolean | Dispatch<SetStateAction<boolean>>' are callable.
    Type 'string' has no call signatures.

Я особенно озадачен, почему он думает, что setErr имеет тип string, когда он должен быть равен функции setNameError, деструктурированной из useState.

Ответы [ 2 ]

1 голос
/ 10 апреля 2020

Все, что вам нужно, это добавить as const к объявлению errors:

  const errors = [
        [setNameError, name.length],
        [setEmailError, email.length]
   ] as const;

Таким образом, массивы будут напечатаны не как массивы, а как кортежи.

0 голосов
/ 10 апреля 2020

Предполагаемый тип errors - это то, что стреляет в вас здесь. По вашему сообщению об ошибке мы можем получить это const errors: (string | number | boolean | Dispatch<SetStateAction<boolean>>)[][], следовательно, машинописный код выводит, что элементы массива могут быть множеством вещей, некоторые из которых не могут быть вызваны. Вместо этого вы можете объективировать его, и выведенные типы будут назначены на ключи, что позволит вам правильно деконструировать и вызывать, то есть

<button
  onClick={() => {
    const errors = [
      {setError:setNameError, condition:name.length},
      {setError:setEmailError, condition:email.length}
    ];

    let canSubmit = true;
    errors.forEach(validation => {
      const {setError, condition} = validation;
      console.log(!condition);
      if (!condition) {
        canSubmit = false;
        setError(true); // <---- ERROR HERE
      }
    });

    if (canSubmit) { /* submit the form */ } 
  }}
>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...