React-dnd: рдЖрдИрдлреНрд░реЗрдо рдореЗрдВ рдмрд╛рд╣рд░ рдЦреАрдВрдЪрдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛

рдХреЛ рдирд┐рд░реНрдорд┐рдд 1 рдЕрдЧре░ 2019  ┬╖  6рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: react-dnd/react-dnd

рдХреНрдпрд╛ рдЖрдкрдХрд╛ рдлреАрдЪрд░ рдЕрдиреБрд░реЛрдз рдХрд┐рд╕реА рд╕рдорд╕реНрдпрд╛ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИ?
рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдПрдХ HTML рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХреЗ рднреАрддрд░ рдбреНрд░реИрдЧ-рдПрдВрдб-рдбреНрд░реЙрдк рдХреЛ рд╕реАрдорд┐рдд рдХрд░рддреА рд╣реИред рдХрд┐рд╕реА рддрд░рд╣ рд╣рдореЗрдВ рдХреБрдЫ рдмрд╛рд╣рд░ iframe рдЕрдВрджрд░ рдЦреАрдВрдЪрдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИред

рдЖрдк рдЬреЛ рд╕рдорд╛рдзрд╛рди рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдЙрд╕рдХрд╛ рд╡рд░реНрдгрди рдХрд░реЗрдВ
рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ dnd HTML5backend рдмрд╕ рд╡рд┐рдВрдбреЛ рдореЗрдВ рдбреНрд░реИрдЧ рдХреЙрд▓рдмреИрдХ рдЯреНрд░рд┐рдЧрд░ рдХрд░рддрд╛ рд╣реИред рддреЛ рдЕрдЧрд░ рд╣рдо рдЖрдИрдлреНрд░реЗрдо рдХреЗ рдЕрдВрджрд░ рдШрдЯрдХреЛрдВ рдХреЛ рдХреЙрд▓рдмреИрдХ рдЯреНрд░рд┐рдЧрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдФрд░ React.createPortal рдЖрдИрдлреНрд░реЗрдо рдХреЗ рдЕрдВрджрд░ рдШрдЯрдХреЛрдВ рдХреЛ рдмрд╛рд╣рд░ рдХреЗ рд╕рд╛рде рдПрдХ рд╣реА рдбреАрдПрдирдбреАрдкреНрд░реЛрд╡рд╛рдЗрдбрд░ рд╣реИред рдпрд╣ рд╕реМрднрд╛рдЧреНрдп рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдЪрд┐рдВрддрд╛ рд╣реИ рдХрд┐ рдХреБрдЫ рд╕рдорд╕реНрдпрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ рдЬрд┐рд╕ рдкрд░ рдореИрдВрдиреЗ рдзреНрдпрд╛рди рдирд╣реАрдВ рджрд┐рдпрд╛ред рдФрд░ рдХреЛрдб HTML5 рдмреИрдХрдПрдВрдб рдХреЗ рд╕рд╛рде рдЗрддрдирд╛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдирд╣реАрдВ рд╣реИред

import React, {
  useRef,
  useEffect,
  useContext,
  forwardRef,
} from 'react';
import classnames from 'classnames';
import { DndContext } from 'react-dnd';

// Frame base on createPortal inside iframe dom.
import Frame from 'react-frame-component';

const events = [
  ['dragstart', 'handleTopDragStart', false],
  ['dragstart', 'handleTopDragStartCapture', true],
  ['dragend', 'handleTopDragEndCapture', true],
  ['dragenter', 'handleTopDragEnter', false],
  ['dragenter', 'handleTopDragEnterCapture', true],
  ['dragleave', 'handleTopDragLeaveCapture', true],
  ['dragover', 'handleTopDragOver', false],
  ['dragover', 'handleTopDragOverCapture', true],
  ['drop', 'handleTopDrop', false],
  ['drop', 'handleTopDropCapture', true],
];

export const DndFrame = forwardRef((props = {}, ref) => {
  const container = useRef(null);
  const dndValue = useContext(DndContext) || {};

  const { dragDropManager: { backend = {} } = {} } = dndValue;
  const { children, className, containerProps = {}, ...others } = props;

  const cls = classnames({
    'dnd-frame': true,
    [className]: !!className,
  });

  useEffect(() => {
    const { current } = container;

    if (!current) {
      return;
    }

    // this make callback run in outside window
    events.forEach((eventArgs = []) => {
      const [name, callbackName, capture = false] = eventArgs;

      const callback = backend[callbackName] && backend[callbackName].bind(backend);

      current.addEventListener(name, (...args) => {
        callback && callback(...args);
      }, capture);
    });
  }, [container.current]);

  return (
    <Frame className={cls} ref={ref} {...others}>
      <div className="dnd-frame-container" ref={container} {...containerProps}>
        { children }
      </div>
    </Frame>
  );
});

рдЙрди рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реЗрдВ рдЬрд┐рди рдкрд░ рдЖрдкрдиреЗ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рд╣реИ
рдХреНрдпрд╛ рдЖрдк HTML5Backend рдХреЗ рд╕рд╛рде рдХреБрдЫ рд╡рд┐рдХрд▓реНрдк рдирд┐рд░реНрдпрд╛рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

design decisions enhancement pinned

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдореБрдЭреЗ рдЗрд╕ рдХреЛрдб рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрд╕рд╛рди рд╕рдорд╛рдзрд╛рди рдорд┐рд▓рд╛, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдмреЗрд╣рддрд░ рд╕рдорд╛рдзрд╛рди рд╣реИ рдпрд╛ рдирд╣реАрдВред рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдЖрдк рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдВрдЧреЗред

import React, { useContext, useEffect } from 'react';
import DndProvider, { DndContext } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import Frame, { FrameContext } from 'react-frame-component';

const DndFrame = ({ children }) => {
  const { dragDropManager } = useContext(DndContext);
  const { window } = useContext(FrameContext);

  useEffect(() => {
    dragDropManager.getBackend().addEventListeners(window);
  });

  return children;
};

const Example = () => (
  <DndProvider backend={HTML5Backend}>
    <Frame>
       <DndFrame>
          <div>...</div>
       </DndFrame>
    </Frame>
  </DndProvider>
);

рд╕рднреА 6 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдореБрдЭреЗ рдЗрд╕ рдХреЛрдб рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрд╕рд╛рди рд╕рдорд╛рдзрд╛рди рдорд┐рд▓рд╛, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдмреЗрд╣рддрд░ рд╕рдорд╛рдзрд╛рди рд╣реИ рдпрд╛ рдирд╣реАрдВред рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдЖрдк рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдВрдЧреЗред

import React, { useContext, useEffect } from 'react';
import DndProvider, { DndContext } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import Frame, { FrameContext } from 'react-frame-component';

const DndFrame = ({ children }) => {
  const { dragDropManager } = useContext(DndContext);
  const { window } = useContext(FrameContext);

  useEffect(() => {
    dragDropManager.getBackend().addEventListeners(window);
  });

  return children;
};

const Example = () => (
  <DndProvider backend={HTML5Backend}>
    <Frame>
       <DndFrame>
          <div>...</div>
       </DndFrame>
    </Frame>
  </DndProvider>
);

@HsuTing рдпрд╣ рдЖрд╕рд╛рди рдФрд░ рдмреЗрд╣рддрд░ рд╣реИред рд▓реЗрдХрд┐рди рдЕрднреА рднреА HTML5Backend рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рд▓рд┐рдП рдмрд╛рдзреНрдп рд╣реИред рдпрджрд┐ HTML5Backend addEventListeners => addListeners рдХреЛ рдмрджрд▓рддрд╛ рд╣реИ, рддреЛ рд╣рдорд╛рд░рд╛ рд╡реЗрдм рдЯреВрдЯ рдЬрд╛рдПрдЧрд╛

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрдЪреНрдЫрд╛ рд╡рд┐рдЪрд╛рд░, рдЬрдм рдореИрдВ рд╣рд╛рдЗрдХ рд╕реЗ рд╡рд╛рдкрд╕ рдЖрдКрдВрдЧрд╛ рддреЛ рдореИрдВ рдЗрд╕рдХреЗ рд╕рд╛рде рдЦреЗрд▓реВрдВрдЧрд╛

рдордВрдЧрд▓рд╡рд╛рд░, рдЕрдЧрд╕реНрдд 6, 2019, рд░рд╛рдд 11:43 рдмрдЬреЗ [email protected] рдиреЗ рд▓рд┐рдЦрд╛:

@HsuTing https://github.com/HsuTing рдпрд╣ рдЖрд╕рд╛рди рдФрд░ рдмреЗрд╣рддрд░ рд╣реИред рдлрд┐рд░ рднреА
HTML5Backend рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рд▓рд┐рдП рдмрд╛рдзреНрдпред рдпрджрд┐ HTML5рдмреИрдХрдПрдВрдб рдПрдбрдПрд╡реЗрдВрдЯ рд▓рд┐рд╕реНрдЯрдирд░ рдмрджрд▓рддрд╛ рд╣реИ
=> рд╢реНрд░реЛрддрд╛рдУрдВ рдХреЛ рдЬреЛрдбрд╝реЗрдВ, рд╣рдорд╛рд░рд╛ рд╡реЗрдм рдЯреВрдЯ рдЬрд╛рдПрдЧрд╛

-
рдЖрдк рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХреЛ рдЕрд╕рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдЗрд╕ рдИрдореЗрд▓ рдХрд╛ рд╕реАрдзреЗ рдЙрддреНрддрд░ рджреЗрдВ, рдЗрд╕реЗ GitHub рдкрд░ рджреЗрдЦреЗрдВ
рдХреЙрдо
рдпрд╛ рдереНрд░реЗрдб рдХреЛ рдореНрдпреВрдЯ рдХрд░реЗрдВ
https://github.com/notifications/unsubscribe-auth/AAA3XCGHNHO3M3CSL5VRUQTQDJVJLANCNFSM4IIMWOQQ
.

рдореБрдЭреЗ рдЗрд╕ рдХреЛрдб рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрд╕рд╛рди рд╕рдорд╛рдзрд╛рди рдорд┐рд▓рд╛, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдмреЗрд╣рддрд░ рд╕рдорд╛рдзрд╛рди рд╣реИ рдпрд╛ рдирд╣реАрдВред рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдЖрдк рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдВрдЧреЗред

import React, { useContext, useEffect } from 'react';
import DndProvider, { DndContext } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import Frame, { FrameContext } from 'react-frame-component';

const DndFrame = ({ children }) => {
  const { dragDropManager } = useContext(DndContext);
  const { window } = useContext(FrameContext);

  useEffect(() => {
    dragDropManager.getBackend().addEventListeners(window);
  });

  return children;
};

const Example = () => (
  <DndProvider backend={HTML5Backend}>
    <Frame>
       <DndFrame>
          <div>...</div>
       </DndFrame>
    </Frame>
  </DndProvider>
);

рдпрд╣ рдПрдХ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рд╣реИ рдФрд░ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

рдореБрдЭреЗ рдЗрд╕ рдХреЛрдб рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрд╕рд╛рди рд╕рдорд╛рдзрд╛рди рдорд┐рд▓рд╛, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдмреЗрд╣рддрд░ рд╕рдорд╛рдзрд╛рди рд╣реИ рдпрд╛ рдирд╣реАрдВред рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдЖрдк рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдВрдЧреЗред

import React, { useContext, useEffect } from 'react';
import DndProvider, { DndContext } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import Frame, { FrameContext } from 'react-frame-component';

const DndFrame = ({ children }) => {
  const { dragDropManager } = useContext(DndContext);
  const { window } = useContext(FrameContext);

  useEffect(() => {
    dragDropManager.getBackend().addEventListeners(window);
  });

  return children;
};

const Example = () => (
  <DndProvider backend={HTML5Backend}>
    <Frame>
       <DndFrame>
          <div>...</div>
       </DndFrame>
    </Frame>
  </DndProvider>
);

рдЯрд╛рдЗрдкрдкреНрд░рддрд┐ рдХреЗ рд╕рд╛рде рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╕рдордп рдореБрдЭреЗ рдПрдХ рддреНрд░реБрдЯрд┐ рдорд┐рд▓рддреА рд╣реИ Property 'addEventListeners' does not exist on type 'Backend'

рдХреНрдпрд╛ рдЯреАрдПрд╕ рдореЗрдВ рдЗрд╕реЗ рдареАрдХ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рд╣реИ?

addEventListeners рдмреИрдХрдПрдВрдб рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкрд░ рдЙрдЬрд╛рдЧрд░ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ; рдФрд░ рдореИрдВ рдЗрд╕рдХрд╛ рдЦреБрд▓рд╛рд╕рд╛ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдбреЛрдо/рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╣реИред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдореЗрдВ рдЬреЛ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рд╡рд╣ рдХреБрдЫ рдРрд╕рд╛ рд╣реИ:

// detect if SSR mode
const DEFAULT_GLOBAL_CONTEXT = typeof window !== 'undefined' ? window : global

const DndFrame = ({ children, globalContext = DEFAULT_GLOBAL_CONTEXT}) => {
  const { dragDropManager } = useContext(DndContext);
  const { window } = useContext(FrameContext);
  const backend = useMemo(() => dragDropManager.getBackend(), [dragDropManager])

  useEffect(() => {
     // This will required adding an initialize() method to the Backend interface.
    // Backend constructors will have to thunk over to it. It could replace constructors, but that would be semver major.
    backend.initialize(dragDropManager, globalContext)
    backend.setup()
  }, [globalContext]);

  return children;
};

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

dreamcog picture dreamcog  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

mx2323 picture mx2323  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

bebbi picture bebbi  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

vickyvxr picture vickyvxr  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

yaoyuande picture yaoyuande  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ