I am starting to learn React Drag and Drop from http://react-dnd.github.io/react-dnd/docs-tutorial.html
But I am having problems understanding the tutorial. Next are all the files I created but at compilation I get:
dragDropBundle.js:830 Warning: Failed prop type: The prop
`connectDropTarget` is marked as required in `BoardSquare`, but its value is `undefined`.
in BoardSquare (created by Board)
in Board (created by DragDropContext(Board))
in DragDropContext(Board)
and
dragDropBundle.js:31408 Uncaught TypeError: connectDropTarget is not a function
at BoardSquare.render (dragDropBundle.js:31408)
at dragDropBundle.js:16370
Can someone explain me please what is wrong? I am reading this tutorial several times and hitting the wall with it.
Here it is the content of my file entry.js
from where my program starts:
import React from "react";
import ReactDOM from "react-dom";
import Square from "./Square.jsx";
import Board from "./Board.jsx";
import Knight from "./Knight.jsx";
import { observe } from "./Game.jsx";
import { canMoveKnight, moveKnight } from "./Game.jsx";
const rootEl = document.getElementById("root");
observe(knightPosition =>
ReactDOM.render(<Board knightPosition={knightPosition} />, rootEl)
);
Here it is the content of my file Board.jsx
:
import React, { Component } from "react";
import { DragDropContext } from "react-dnd";
import HTML5Backend from "react-dnd-html5-backend";
import PropTypes from "prop-types";
import Square from "./Square.jsx";
import Knight from "./Knight.jsx";
import { canMoveKnight, moveKnight } from "./Game.jsx";
import { BoardSquare } from "./BoardSquare.jsx";
export class Board extends Component {
renderPiece(x, y) {
const [knightX, knightY] = this.props.knightPosition;
if (x === knightX && y === knightY) {
return <Knight />;
}
}
renderSquare(i) {
const x = i % 8;
const y = Math.floor(i / 8);
return (
<div key={i} style={{ width: "12.5%", height: "12.5%" }}>
<BoardSquare x={x} y={y}>
{this.renderPiece(x, y)}
</BoardSquare>
</div>
);
}
handleSquareClick(toX, toY) {
if (canMoveKnight(toX, toY)) {
moveKnight(toX, toY);
}
}
render() {
console.log(this.props.knightPosition);
const squares = [];
for (let i = 0; i < 64; i++) {
squares.push(this.renderSquare(i));
}
return (
<div
style={{
width: "100%",
height: "100%",
display: "flex",
flexWrap: "wrap"
}}
>
{squares}
</div>
);
}
}
Board.propTypes = {
knightPosition: PropTypes.arrayOf(PropTypes.number.isRequired).isRequired
};
export default DragDropContext(HTML5Backend)(Board);
Here it is the content of my file Knight.jsx
:
import React, { Component } from "react";
import PropTypes from "prop-types";
import { ItemTypes } from "./Constants.jsx";
import { DragSource } from "react-dnd";
const knightSource = {
beginDrag(props) {
return {};
}
};
function collect(connect, monitor) {
return {
connectDragSource: connect.dragSource(),
isDragging: monitor.isDragging()
};
}
class Knight extends Component {
render() {
const { connectDragSource, isDragging } = this.props;
return connectDragSource(
<div
style={{
opacity: isDragging ? 0.5 : 1,
fontSize: 25,
fontWeight: "bold",
cursor: "move"
}}
>
♘
</div>
);
}
}
Knight.propTypes = {
connectDragSource: PropTypes.func.isRequired,
isDragging: PropTypes.bool.isRequired
};
export default DragSource(ItemTypes.KNIGHT, knightSource, collect)(Knight);
Here it is the content of my file Square.jsx
:
import React, { Component } from "react";
import PropTypes from "prop-types";
export default class Square extends Component {
render() {
const { black } = this.props;
const fill = black ? "black" : "white";
const stroke = black ? "white" : "black";
return (
<div
style={{
backgroundColor: fill,
color: stroke,
width: "100%",
height: "100%"
}}
>
{this.props.children}
</div>
);
}
}
Square.propTypes = {
black: PropTypes.bool
};
Here it is the content of my file: BoardSquare.jsx
import React, { Component } from "react";
import PropTypes from "prop-types";
import Square from "./Square.jsx";
import { canMoveKnight, moveKnight } from "./Game.jsx";
import { ItemTypes } from "./Constants.jsx";
import { DropTarget } from "react-dnd";
const squareTarget = {
drop(props) {
moveKnight(props.x, props.y);
}
};
function collect(connect, monitor) {
return {
connectDropTarget: connect.dropTarget(),
isOver: monitor.isOver()
};
}
export class BoardSquare extends Component {
render() {
const { x, y, connectDropTarget, isOver } = this.props;
const black = (x + y) % 2 === 1;
return connectDropTarget(
<div
style={{
position: "relative",
width: "100%",
height: "100%"
}}
>
<Square black={black}>{this.props.children}</Square>
{isOver && (
<div
style={{
position: "absolute",
top: 0,
left: 0,
height: "100%",
width: "100%",
zIndex: 1,
opacity: 0.5,
backgroundColor: "yellow"
}}
/>
)}
</div>
);
}
}
BoardSquare.propTypes = {
x: PropTypes.number.isRequired,
y: PropTypes.number.isRequired,
connectDropTarget: PropTypes.func.isRequired,
isOver: PropTypes.bool.isRequired
};
export default DropTarget(ItemTypes.KNIGHT, squareTarget, collect)(BoardSquare);