Cześć!
Mam problem z reactem którego kompletnie nie rozumiem.
Mam 4 pliki:
Generator.js:
import React, { Component } from 'react';
import update from 'react/lib/update';
import { DragDropContext } from 'react-dnd';
import HTML5Backend, { NativeTypes } from 'react-dnd-html5-backend';
import Dustbin from './Dustbin';
import Box from './Box';
import ItemTypes from './ItemTypes';
class Generator extends Component {
constructor(props) {
super(props);
this.state = {
dustbins: [
{ accepts: [ItemTypes.GLASS], lastDroppedItem: null },
{ accepts: [ItemTypes.FOOD], lastDroppedItem: null },
{ accepts: [ItemTypes.PAPER, ItemTypes.GLASS, NativeTypes.URL], lastDroppedItem: null },
{ accepts: [ItemTypes.PAPER, NativeTypes.FILE], lastDroppedItem: null },
],
boxes: [
{ name: 'Bottle', type: ItemTypes.GLASS },
{ name: 'Banana', type: ItemTypes.FOOD },
{ name: 'Magazine', type: ItemTypes.PAPER },
],
droppedBoxNames: [],
};
}
isDropped(boxName) {
return this.state.droppedBoxNames.indexOf(boxName) > -1;
}
render() {
const { boxes, dustbins } = this.state;
return (
<div>
<div style={{ overflow: 'hidden', clear: 'both' }}>
{dustbins.map(({ accepts, lastDroppedItem }, index) =>
<Dustbin
accepts={accepts}
lastDroppedItem={lastDroppedItem}
onDrop={item => this.handleDrop(index, item)}
key={index}
/>,
)}
</div>
<div style={{ overflow: 'hidden', clear: 'both' }}>
{boxes.map(({ name, type }, index) =>
<Box
name={name}
type={type}
isDropped={this.isDropped(name)}
key={index}
/>,
)}
</div>
</div>
);
}
handleDrop(index, item) {
const { name } = item;
this.setState(update(this.state, {
dustbins: {
[index]: {
lastDroppedItem: {
$set: item,
},
},
},
droppedBoxNames: name ? {
$push: [name],
} : {},
}));
}
}
export default DragDropContext(HTML5Backend)(Generator);
Dustbin.js
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { DropTarget } from 'react-dnd';
const style = {
height: '12rem',
width: '12rem',
marginRight: '1.5rem',
marginBottom: '1.5rem',
color: 'white',
padding: '1rem',
textAlign: 'center',
fontSize: '1rem',
lineHeight: 'normal',
float: 'left',
};
const dustbinTarget = {
drop(props, monitor) {
props.onDrop(monitor.getItem());
},
};
class Dustbin extends Component {
render() {
const { accepts, isOver, canDrop, connectDropTarget, lastDroppedItem } = this.props;
const isActive = isOver && canDrop;
let backgroundColor = '#222';
if (isActive) {
backgroundColor = 'darkgreen';
} else if (canDrop) {
backgroundColor = 'darkkhaki';
}
return connectDropTarget(
<div style={{ ...style, backgroundColor }}>
{isActive ?
'Release to drop' :
`This dustbin accepts: ${accepts.join(', ')}`
}
{lastDroppedItem &&
<p>Last dropped: {JSON.stringify(lastDroppedItem)}</p>
}
</div>,
);
}
}
Dustbin.propTypes = {
connectDropTarget: PropTypes.func.isRequired,
isOver: PropTypes.bool.isRequired,
canDrop: PropTypes.bool.isRequired,
accepts: PropTypes.arrayOf(PropTypes.string).isRequired,
lastDroppedItem: PropTypes.object,
onDrop: PropTypes.func.isRequired,
};
export default DropTarget(props => props.accepts, dustbinTarget, (connect, monitor) => ({
connectDropTarget: connect.dropTarget(),
isOver: monitor.isOver(),
canDrop: monitor.canDrop(),
}))(Dustbin);
ItemTypes.js
export default {
FOOD: 'food',
GLASS: 'glass',
PAPER: 'paper',
};
Box.js
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { DragSource } from 'react-dnd';
const style = {
border: '1px dashed gray',
backgroundColor: 'white',
padding: '0.5rem 1rem',
marginRight: '1.5rem',
marginBottom: '1.5rem',
cursor: 'move',
float: 'left',
};
const boxSource = {
beginDrag(props) {
return {
name: props.name,
};
},
};
class Box extends Component {
static propTypes = {
connectDragSource: PropTypes.func.isRequired,
isDragging: PropTypes.bool.isRequired,
name: PropTypes.string.isRequired,
type: PropTypes.string.isRequired,
isDropped: PropTypes.bool.isRequired,
};
render() {
const { name, isDropped, isDragging, connectDragSource } = this.props;
const opacity = isDragging ? 0.4 : 1;
return connectDragSource(
<div style={{ ...style, opacity }}>
{isDropped ?
<s>{name}</s> :
name
}
</div>,
);
}
}
export default DragSource(props => props.type, boxSource, (connect, monitor) => ({
connectDragSource: connect.dragSource(),
isDragging: monitor.isDragging(),
}))(Box);
Jest to kod z https://github.com/react-dnd/react-dnd/tree/master/examples/01%20Dustbin/Multiple%20Targets delikatnie zmodyfikowany pod ES6
Niestety, w konsoli dostaję takie błędy:
warning.js:35 Warning: Failed prop type: Invalid prop
component
supplied toRoute
.
in Route (at index.js:30)
in App (at index.js:36)
printWarning @ warning.js:35
warning @ warning.js:59
checkReactTypeSpec @ checkReactTypeSpec.js:80
validatePropTypes @ ReactElementValidator.js:162
createElement @ ReactElementValidator.js:216
App_render @ index.js:30
(anonymous) @ ReactCompositeComponent.js:795
measureLifeCyclePerf @ ReactCompositeComponent.js:75
_renderValidatedComponentWithoutOwnerOrContext @ ReactCompositeComponent.js:794
_renderValidatedComponent @ ReactCompositeComponent.js:821
performInitialMount @ ReactCompositeComponent.js:361
mountComponent @ ReactCompositeComponent.js:257
mountComponent @ ReactReconciler.js:45
performInitialMount @ ReactCompositeComponent.js:370
mountComponent @ ReactCompositeComponent.js:257
mountComponent @ ReactReconciler.js:45
mountComponentIntoNode @ ReactMount.js:104
perform @ Transaction.js:143
batchedMountComponentIntoNode @ ReactMount.js:126
perform @ Transaction.js:143
batchedUpdates @ ReactDefaultBatchingStrategy.js:62
batchedUpdates @ ReactUpdates.js:97
_renderNewRootComponent @ ReactMount.js:319
_renderSubtreeIntoContainer @ ReactMount.js:401
render @ ReactMount.js:422
(anonymous) @ index.js:36
webpack_require @ bootstrap ed8463e505d8222609fe:555
fn @ bootstrap ed8463e505d8222609fe:86
(anonymous) @ bootstrap ed8463e505d8222609fe:578
webpack_require @ bootstrap ed8463e505d8222609fe:555
(anonymous) @ bootstrap ed8463e505d8222609fe:578
(anonymous) @ bootstrap ed8463e505d8222609fe:578
browser.js:40 Uncaught Error: The root route must render a single element
at invariant (browser.js:40)
at Object.render (RouterContext.js:149)
at ReactCompositeComponent.js:795
at measureLifeCyclePerf (ReactCompositeComponent.js:75)
at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (ReactCompositeComponent.js:794)
at ReactCompositeComponentWrapper._renderValidatedComponent (ReactCompositeComponent.js:821)
at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:361)
at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:257)
at Object.mountComponent (ReactReconciler.js:45)
at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:370)
O ile rozumiem co one oznaczają to za nic nie potrafię stwierdzić a tym bardziej rozwiązać przyczyny ich występowania więc proszę Was o pomoc.
Z góry dzięki wielkie :)