Задать вопрос
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
  • Вопрос задан
  • 150 просмотров
Подписаться 1 Простой 4 комментария
Помогут разобраться в теме Все курсы
  • Нетология
    Frontend-разработка на React
    10 недель
    Далее
  • ProductStar
    Разработка на React
    6 недель
    Далее
  • Яндекс Практикум
    React-разработчик
    3 месяца
    Далее
Решения вопроса 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
Ваш ответ на вопрос

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

Похожие вопросы
от 250 000 до 300 000 ₽
ITK academy Нижний Новгород
от 50 000 до 90 000 ₽
ITK academy Екатеринбург
от 50 000 до 90 000 ₽