Typescript Реагирует на пользовательский крючок ссылка на элемент div

0

Вопрос

ИЗМЕНИТЬ: Я настроил кодовое поле: https://codesandbox.io/s/magical-poitras-yogur?file=/src/App.tsx

Я пытаюсь создать пользовательский хук для элемента div в react, чтобы добавить прослушиватели событий.

Я нашел это "общее" решение:

function useMyCustomHook<T extends HTMLElement>{
    const myRef = useRef<T>(null)

    // do something with the ref, e.g. adding event listeners

    return {ref: myRef}
}

function MyComponent(){
    const {ref: myElementRef} = useMyCustomHook<HTMLDivElement>()

    return <div ref={myElementRef}>A Div</div>
}

от: Не удается назначить RefObject<HTMLDivElement> для RefObject<HTMLDivElement><HTMLElement> экземпляр<HTMLElement>

Который я попытался реализовать в своем коде ниже. Я играл в течение нескольких часов и, наконец, свел все к одной ошибке, но я не знаю, как ее решить. Ошибка в моем useHover выражение функции на первом =. ошибка заключается в: '(' expected.ts(1005)

теперь мой код:

const Hooks = (props: any) => {
    const [hoverRef, hovered] = useHover();
    const style = {
        backgroundColor: hovered ? "red" : "",
    };

    return (
        <div ref={hoverRef} style={style}>
            <h1>Hooks!</h1>
        </div>
    );
};

                                          
const useHover:<HTMLDivElement extends HTMLElement> = () => {
                                      // ERROR HERE ^ the first equal sign. '(' expected.ts(1005)
    const [value, setValue] = useState(false);
    const ref = useRef<HTMLDivElement>(null);

    const handleMouseOver = () => setValue(true);

    useEffect(() => {
        const node = ref.current;
        if (node) {
            node.addEventListener("mouseover", handleMouseOver);

            return () => {
                node.removeEventListener("mouseover", handleMouseOver);
            }
        }
    }, []);

    return [ref, value];
};

Любая помощь будет признательна!

react-hooks reactjs typescript
2021-11-24 05:57:28
1

Лучший ответ

1

Попробуйте это: вместо использования ref и обязательно манипулируя собственными событиями DOM, создавайте атрибуты элементов для событий, которые вы хотите обработать, и возвращайте их для использования с вашим элементом React:

Примечание: Вы можете игнорировать CSS и первые четыре <script> элементы (они просто существуют для того, чтобы синтаксис TypeScript React работал в демонстрационном фрагменте).

body {
  font-family: sans-serif;
}

.target {
  border: 1px solid;
  padding: 1rem;
}
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/[email protected]/babel.min.js"></script>
<script>Babel.registerPreset('tsx', {presets: [[Babel.availablePresets['typescript'], {allExtensions: true, isTSX: true}]]});</script>

<div id="root"></div>

<script type="text/babel" data-type="module" data-presets="tsx,react">

/**
 * The following line is here because this Stack Overflow snippet uses the
 * UMD module for React. In your code, you'd use the commented `import` lines
 * below it.
 */
const {useMemo, useState} = React;

// import {useMemo, useState} from 'react';
// import type {DetailedHTMLProps, HTMLAttributes, ReactElement} from 'react';

type HoverData<T extends HTMLElement> = {
  hoverProps: DetailedHTMLProps<HTMLAttributes<T>, T>;
  isHovered: boolean;
};

function useHover <T extends HTMLElement>(): HoverData<T> {
  const [isHovered, setIsHovered] = useState(false);

  const hoverProps: HoverData<T>['hoverProps'] = useMemo(() => ({
    onMouseEnter: () => setIsHovered(true),
    onMouseLeave: () => setIsHovered(false),
  }), [setIsHovered]);

  return {hoverProps, isHovered};
}

function Example (): ReactElement {
  const {hoverProps, isHovered} = useHover<HTMLDivElement>();

  return (
    <div>
      <h1>Hover the text below</h1>
      <div {...hoverProps} className="target">
        {isHovered ? 'Now move it away' : 'Move pointer here'}
      </div>
    </div>
  );
}

ReactDOM.render(<Example />, document.getElementById('root'));

</script>

2021-11-29 06:48:48

На других языках

Эта страница на других языках

Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................