Задать вопрос
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
  • Вопрос задан
  • 131 просмотр
Подписаться 1 Простой 4 комментария
Решения вопроса 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
Ваш ответ на вопрос

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

Похожие вопросы