Реагировать - не вызываемое выражение - PullRequest
2 голосов
/ 24 апреля 2020

В React настроен следующий код.

const useToggle = (initialValue : boolean) => {
  const [bool, setBool] = useState(initialValue)
  const toggle = () => {
    setBool(!bool)
  }
  return [bool, toggle]
}

const Test : FC = () => {
  const [bool, toggle] = useToggle(false)  
  return (    
    <div>
      boolean value: {bool}
      <button onClick={() => {
        toggle()
      }}>Toggle</button>

    </div>

  )
}

В строке с toggle() Я получаю следующую ошибку:

This expression is not callable. Not all constituents of type 'boolean | (() => void)' are callable. Type 'false' has no call signatures.

Однако ошибка исчезнет, ​​если я заменит элемент <button> следующим образом:

<button onClick={() => toggle}>

Я не совсем понимаю, в чем разница. Как именно это исправить ошибку?

1 Ответ

2 голосов
/ 24 апреля 2020

Ошибка исчезает, потому что в этой версии: <button onClick={() => toggle}> вы на самом деле не вызываете функцию. Вы создали функцию стрелки, которая возвращает ссылку на функцию toggle.

В вашем методе useToggle используйте const assertion или явное объявление типа для метода:

// const assertion
const useToggle = (initialValue : boolean) => {
  const [bool, setBool] = useState(initialValue)
  const toggle = () => {
    setBool(!bool)
  }
  return [bool, toggle] as const;
}

const Test : FC = () => {
  const [bool, toggle] = useToggle(false)  
  return (    
    <div>
      boolean value: {bool}
      <button onClick={() => {
        toggle()
      }}>Toggle</button>

    </div>

  )
}
// return type declaration
// const assertion
const useToggle = (initialValue : boolean) : [string, Function] => {
  const [bool, setBool] = useState(initialValue)
  const toggle = () => {
    setBool(!bool)
  }
  return [bool, toggle];
}

const Test : FC = () => {
  const [bool, toggle] = useToggle(false)  
  return (    
    <div>
      boolean value: {bool}
      <button onClick={() => {
        toggle()
      }}>Toggle</button>

    </div>

  )
}

Причина, по которой эта проблема существует, имеет делать с Tuple типами (что возвращают хуки React). Так как ваш метод useToggle не указал, что возвращалось из функции, TS пытается определить это. Он видит литерал Array и печатает его как литерал Array, не понимая основные типы внутри. Существует выдающийся RF C, чтобы изменить это поведение, но добавление правильных типов (или исправление константного утверждения) обходит это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...