Kontener <div> z resizowalnym rozmiarem

0

Hej, chce stworzyc customowy resizer do mojego diva w ReactJS. Zrobilem tak jak w kodzie ponizej (czyli zawsze document.getElementById()) i dziala ale zastanawiam sie czy jest to dobrze napisane czy nieelegancko i istnieje lepsza metoda zgodna z ReactJS? Myslalem zeby jakos refa podac ale probowalem zastapic document.getElementById() przez ref.current i nie dzialalo.


  const ResizeHandle = ({
    targetRef,
  }: {
    targetRef: React.RefObject<HTMLDivElement>;
  }) => {
    let resizerRef = useRef<HTMLDivElement>(null);

    let currentPosition: number;
    let mouseDown: boolean;
    let lastClientY: number;

    function touchMouseStart(e: any) {
      e.preventDefault();
      // if (!targetRef.current) return;

      mouseDown = true;
      if (e.touches) currentPosition = e.touches[0].clientY;
      else currentPosition = e.clientY;
      lastClientY = document.getElementById('editor-content')!.offsetHeight;

      // console.log("LastClientY");
      // console.log(lastClientY);

      // document.addEventListener("mousemove", documentHorizontalMouseMove);
      // document.addEventListener("mouseup", stopHorizontalResize);
    }

    function touchMouseEnd(e: any) {
      e.preventDefault();
      // if (!targetRef.current) return;

      mouseDown = false;
      lastClientY = document.getElementById('editor-content')!.offsetHeight;

      // lastClientY = ref.current?.offsetHeight;
      // console.log("LastClientY");
      // console.log(lastClientY);
    }

    function touchMouseMove(e: any) {
      e.preventDefault();
      // if (!targetRef.current) return;

      if (!mouseDown) return;
      if (e.touches) var position = e.touches[0].clientY;
      else var position = e.clientY;

      // console.log("pozycja");
      // console.log(pozycja);

      var diff = position - currentPosition;

      // console.log("wysokosc");
      // console.log(wysokosc);

      document.getElementById('editor-content')!.style.height =
        lastClientY + diff + 'px';
    }

    return (
      <div
        ref={resizerRef}
        className='mr-0 h-[30px] w-full cursor-s-resize rounded-b-[6px] border-t-[1px] bg-muted '
        onPointerDown={(e: any) =>
          resizerRef.current?.setPointerCapture(e.pointerId)
        }
        onPointerUp={(e: any) =>
          resizerRef.current?.releasePointerCapture(e.pointerId)
        }
        onMouseDown={touchMouseStart}
        onMouseUp={touchMouseEnd}
        onTouchStart={touchMouseStart}
        onTouchEnd={touchMouseEnd}
        onTouchCancel={touchMouseEnd}
        onClick={(e) => e.preventDefault()}
        onTouchMove={touchMouseMove}
        onMouseMove={touchMouseMove}
      ></div>
    );
  };

  return (
    <div
      className={cn(
        'relative z-10 flex w-full flex-col rounded-[6px] border-[1px] border-border bg-background p-0',
        editorVariants({ className, variant })
      )}
    >
      <MenuBar editor={editor!}></MenuBar>
      <EditorContent
        id='editor-content'
        ref={editorContentRef}
        editor={editor}
        className='h-full max-h-full w-full flex-grow-[1] overflow-auto p-[12px] pt-[6px]'
        onClick={() => editor?.commands.focus()}
      />
      {resizable && <ResizeHandle targetRef={editorContentRef} />}
    </div>
  );
0

W React mógłbyś zrobić tak, że wydzielasz zmieniający się kawałek danych (tutaj jak rozumiem wysokość elementu ma się zmieniać) do tzw. stanu. I kiedy chcesz coś zmienić, to zmieniasz stan. I wysokość elementu również możesz napisać jako dane i przekazać jako właściwość style np.

function Foo({ onClick }) {
  return <button onClick={onClick}>click me</button>
}

export default function App() {
  
  const [height, setHeight] = React.useState(100);

  return (
    <div style={{width: 100, height, background: 'red'}}>
      <Foo onClick={() => setHeight(value => value + 20)} />
    </div>
  );
}

tak to działa: https://l72hfr.csb.app/

Również powinieneś przeczytać o tym, w jaki sposób w zasadzie tworzyć komponenty React i jak przekazywać stan z jednego do drugiego:
https://react.dev/learn (oficjalna dokumentacja)
masz tam nawet rysunki, które to ilustrują.

document.getElementById('editor-content')!.style.height = lastClientY + diff + 'px';

To może zadziałać, tylko w tym momencie omijasz całego Reacta. Więc po co w ogóle go używać, skoro i tak piszesz w sposób, w który mógłbyś pisać bez Reacta (bezpośrednio działać na elementach DOM)? Pewnie, czasem się przydaje ominąć Reacta, ale to powinien być wyjątek, a nie reguła.

1 użytkowników online, w tym zalogowanych: 0, gości: 1