React DnD is a React drag-library.

Two squares are now set up with a dock piece inside that can be dragged into other squares


import React, { useContext, useReducer } from 'react'
import { DndProvider, useDrag, useDrop } from 'react-dnd'
import HTML5Backend from 'react-dnd-html5-backend'

import { spirit } from './models'

import style from './style.css'

const GameContext = React.createContext()

function Knight() {
  const [{ isDragging }, drag] = useDrag({
    item: { type: 'knight' },
        collect: monitor => {
      return {
        isDragging: monitor.isDragging(),
      }
    },
  })
  return< div ref = {drag} the className = {style.css. Knight} > ♘ < / div >}function Square({ x, y }) {
  const { state, dispatch } = useContext(GameContext)
  const [{ isOver }, drop] = useDrop({
    accept: 'knight',
    drop: () => dispatch({ type: 'move', x, y }),
    collect: monitor => ({
      isOver: monitor.isOver(),
    }),
  })

  let children = null
  if (state.x === x && state.y === y) {
    children = <Knight x={x} y={y} />
  }
  return <div ref={drop} className={style.square}>{children}</div>
}

function Board({ data }) {
  return (
    <DndProvider backend={HTML5Backend}>
      <Square x={0} y={0} />
      <Square x={1} y={0} />
    </DndProvider>
  )
}

export default function DndDemo(props) {
  const [state, dispatch] = useReducer(spirit.reducer, spirit.state)

  return (
    <GameContext.Provider value={{ state, dispatch }}>
      <Board />
    </GameContext.Provider>
  )
}Copy the code

First of all, don’t worry about what the GameContext and useReducer in DndDemo components do

There are currently three elements

Knight pieces

Lattice Square component

Checkerboard module

The backend attribute is used to specify how the backend backend is used. The backend attribute is used to specify how the backend backend is used. HTML5Backend means that we directly use the API provided by the browser (DND website has more details).

Use the useDrag hook in the Knight component to make the DOM element drag by returning a ref (drag)

Use the useDrop hook in the Square component to enable the actual DOM to be placed. The accept parameter specifies that only elements of type Knight can be placed

So far, the basic configuration is complete

If you drag the horse’s head to another cell, no error is reported, but the horse’s head will not actually go to another cell. To actually move the horse’s head, you need a move function that updates the position of the horse’s head


If the React Context object is used alone, you need to write methods (functions) in DndDemo to update the state. In the react example, state updates are performed using setState


Updating state within a component has several disadvantages

  1. All update methods are written inside the component, which is bloated
  2. For example, if I want to write a move method that actually updates the chess component to a different grid, if I write it in the DndDemo component, then the update logic cannot be used directly in the other top-level Container component and must be copied
  3. If Container is a functional component, flexibility may be limited, and while the React Hook API is very close to normal functions, there are limitations


const spirit = {
  state: {
    x: 0,
    y: 0,
  },
  reducer (state, action) {
    const { type, x, y } = action
    switch (type) {
      case 'move':
        return{... state, x, y } default: throw new Error(); }}}export { spirit }Copy the code

This is./models.js, which is a redux compliant JS code, except that it no longer subscribes to child components using the Observe function of the React-Redux library


The use of context + useReducer naturally supports real modularity. Which section of Redux logic needs to be directly referenced so that redux can be reused in a real sense. The disadvantage is that it becomes difficult for a deducer to update the state in other models


At this point, a drag-and-drop feature is implemented!

(If you are implementing a drag-and-drop game, it is not a good idea to generate children directly in the Square component because one will be destroyed

The elves

The elves