Strojopis Reagovat custom hook ref div element

0

Otázka

EDIT: jsem nastavit codesandbox: https://codesandbox.io/s/magical-poitras-yogur?file=/src/App.tsx

Snažím se vytvořit vlastní háček div prvek reagovat na přidat posluchače událostí.

Našel jsem toto "obecné" řešení:

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>
}

od: Nelze přiřadit RefObject<HTMLDivElement> RefObject<HTMLElement> instance

Které jsem se snažil realizovat v mém kódu níže. Hrál jsem si na hodiny a konečně dostal dolů jen jedna chyba, ale nevím, jak to vyřešit. Chyba je v mé useHover výraz funkce na první =. chyba je: '(' expected.ts(1005)

můj kód:

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];
};

Každá pomoc je vítána!

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

Nejlepší odpověď

1

Zkuste toto: Namísto použití ref a bezpodmínečně manipulování nativní DOM události, vytvořit element atributy pro události, které chcete zvládnout, a návrat těch, pro použití s vaším Reagovat prvku:

Poznámka: můžete ignorovat CSS a první čtyři <script> prvky (jsou tam jen tak, že Strojopisu Reagovat syntaxe bude pracovat v snippet demo).

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

V jiných jazycích

Tato stránka je v jiných jazycích

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