Задать вопрос
DZHAMBULAT-SAMOUCHKA
@DZHAMBULAT-SAMOUCHKA
Frontend разработчик

Что не так с вызовом кастомного хука в React?

Здрасте. У меня есть хук useHint который принимает аргумент время действия подсказки. Когда я пытаюсь вызвать этот хук в onClick выскакивает ошибка в консоли:

Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
at Object.throwInvalidHookError (react-dom_client.js?v=6b6a5873:11521:17)
at Object.useContext (chunk-EPSXJ6EN.js?v=6b6a5873:1062:29)
at useReduxContext2 (react-redux.js?v=6b6a5873:146:32)
at useStore2 (react-redux.js?v=6b6a5873:1137:23)
at useDispatch2 (react-redux.js?v=6b6a5873:1149:19)
at useAppDispatch (reduxHooks.ts:5:10)
at useHint (useHint.ts:5:20)
at Item._jsxDEV.children._jsxDEV.children._jsxDEV.onClick (Item.tsx:30:13)
at HTMLUnknownElement.callCallback2 (react-dom_client.js?v=6b6a5873:3674:22)
at Object.invokeGuardedCallbackDev (react-dom_client.js?v=6b6a5873:3699:24)

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

Код хука:
import { useAppDispatch } from './reduxHooks'
import { setHintState } from '@/store/hint/hintSlice'

const useHint: (hintTime?: number) => void = (hintTime) => {
  const dispatch = useAppDispatch()
  dispatch({ type: setHintState.type, payload: { state: true } })
  setTimeout(() => {
    dispatch({ type: setHintState.type, payload: { state: false } })
  }, hintTime && 300)
}

export default useHint


Место где он применяется:
import CopyButton from '@/components/ui/button/CopyButton'
import useHint from '@/hooks/useHint'


const Item: FC = () => {
  return (
    <>
        <CopyButton
          className='contacts-group-item-field__btn'
          onClick={() => {
            useHint(500)
            navigator.clipboard.writeText('test')
          }}
        />
    </>
  )
}

export default Item
  • Вопрос задан
  • 149 просмотров
Подписаться 1 Простой 4 комментария
Помогут разобраться в теме Все курсы
  • Яндекс Практикум
    React-разработчик
    3 месяца
    Далее
  • ProductStar
    React: отточите навыки интерфейсной разработки
    6 недель
    Далее
  • Skillfactory
    Специализация Frontend-разработчик
    9 месяцев
    Далее
Решения вопроса 1
Alexandroppolus
@Alexandroppolus
кодир
Нельзя просто так взять и вызвать хук в обработчике события. Да, здесь он как бы "внутри" Item, но это обман зрения )

вот так попробуй:
const useHint = (hintTime?: number): VoidFunction => {
  const dispatch = useAppDispatch();

  return () => {
    dispatch({ type: setHintState.type, payload: { state: true } })
    setTimeout(() => {
      dispatch({ type: setHintState.type, payload: { state: false } })
    }, hintTime && 300);
  };
};

...

const Item: FC = () => {
  const runHint = useHint(500);

  return (
    <>
        <CopyButton
          className='contacts-group-item-field__btn'
          onClick={() => {
            runHint(500);
            navigator.clipboard.writeText('test')
          }}
        />
    </>
  )
}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
ITK academy Нижний Новгород
от 50 000 до 90 000 ₽
IT ATLAS Москва
от 200 000 до 250 000 ₽
ITK academy Казань
от 50 000 до 90 000 ₽