Update FileDrop to Hooks

This commit is contained in:
Angelos Chalaris
2019-02-12 20:46:21 +02:00
parent 04d0d1ac83
commit be19eaadd1
3 changed files with 102 additions and 124 deletions

105
README.md
View File

@ -714,12 +714,13 @@ ReactDOM.render(
Renders a file drag and drop component for a single file.
Create a ref called `dropRef` for this component.
Initialize `state.drag` and `state.filename` to `false` and `''` respectively.
The variables `dragCounter` and `state.drag` are used to determine if a file is being dragged, while `state.filename` is used to store the dropped file's name.
Use the `React.useState()` hook to create the `drag` and `filename` variables, initialized to `false` and `''` respectively.
The variables `dragCounter` and `drag` are used to determine if a file is being dragged, while `filename` is used to store the dropped file's name.
Create the `handleDrag`, `handleDragIn`, `handleDragOut` and `handleDrop` methods to handle drag and drop functionality, bind them to the component's context.
Each of the methods will handle a specific event, the listeners for which are created and removed in `componentDidMount` and `componentWillUnmount` respectively.
`handleDrag` prevents the browser from opening the dragged file, `handleDragIn` and `handleDragOut` handle the dragged file entering and exiting the component, while `handleDrop` handles the file being dropped and passes it to `this.props.handleDrop`.
In the `render()` method, create an appropriately styled `<div>` and use `state.drag` and `state.filename` to determine its contents and style.
Each of the methods will handle a specific event, the listeners for which are created and removed in the `React.useEffect()` hook and its attached `cleanup()` method.
`handleDrag` prevents the browser from opening the dragged file, `handleDragIn` and `handleDragOut` handle the dragged file entering and exiting the component, while `handleDrop` handles the file being dropped and passes it to `props.handleDrop`.
Return an appropriately styled `<div>` and use `drag` and `filename` to determine its contents and style.
Finally, bind the `ref` of the created `<div>` to `dropRef`.
@ -743,79 +744,67 @@ Finally, bind the `ref` of the created `<div>` to `dropRef`.
```
```jsx
class FileDrop extends React.Component {
constructor(props) {
super(props);
this.dropRef = React.createRef();
this.state = {
drag: false,
filename: ''
}
this.handleDrag = this.handleDrag.bind(this);
this.handleDragIn = this.handleDragIn.bind(this);
this.handleDragOut = this.handleDragOut.bind(this);
this.handleDrop = this.handleDrop.bind(this);
}
function FileDrop(props) {
const [drag, setDrag] = React.useState(false);
const [filename, setFilename] = React.useState('');
let dropRef = React.createRef();
let dragCounter = 0;
handleDrag(e) {
const handleDrag = e => {
e.preventDefault();
e.stopPropagation();
}
};
handleDragIn(e) {
const handleDragIn = e => {
e.preventDefault();
e.stopPropagation();
this.dragCounter++;
if (e.dataTransfer.items && e.dataTransfer.items.length > 0)
this.setState({ drag: true });
}
dragCounter++;
if (e.dataTransfer.items && e.dataTransfer.items.length > 0) setDrag(true);
};
handleDragOut(e) {
const handleDragOut = e => {
e.preventDefault();
e.stopPropagation();
this.dragCounter--;
if (this.dragCounter === 0)
this.setState({ drag: false });
}
dragCounter--;
if (dragCounter === 0) setDrag(false);
};
handleDrop(e) {
const handleDrop = e => {
e.preventDefault();
e.stopPropagation();
this.setState({ drag: false });
setDrag(false);
if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
this.props.handleDrop(e.dataTransfer.files[0]);
this.setState({ filename : e.dataTransfer.files[0].name});
props.handleDrop(e.dataTransfer.files[0]);
setFilename(e.dataTransfer.files[0].name);
e.dataTransfer.clearData();
this.dragCounter = 0;
}
dragCounter = 0;
}
};
componentDidMount() {
let div = this.dropRef.current;
div.addEventListener('dragenter', this.handleDragIn);
div.addEventListener('dragleave', this.handleDragOut);
div.addEventListener('dragover', this.handleDrag);
div.addEventListener('drop', this.handleDrop);
}
React.useEffect(() => {
let div = dropRef.current;
div.addEventListener("dragenter", handleDragIn);
div.addEventListener("dragleave", handleDragOut);
div.addEventListener("dragover", handleDrag);
div.addEventListener("drop", handleDrop);
return function cleanup() {
div.removeEventListener("dragenter", handleDragIn);
div.removeEventListener("dragleave", handleDragOut);
div.removeEventListener("dragover", handleDrag);
div.removeEventListener("drop", handleDrop);
};
});
componentWillUnmount() {
let div = this.dropRef.current;
div.removeEventListener('dragenter', this.handleDragIn);
div.removeEventListener('dragleave', this.handleDragOut);
div.removeEventListener('dragover', this.handleDrag);
div.removeEventListener('drop', this.handleDrop);
}
render() {
return (
<div ref={this.dropRef} className={this.state.drag ? 'filedrop drag' : this.state.filename ? 'filedrop ready' : 'filedrop'}>
{this.state.filename && !this.state.drag ?
<div>{this.state.filename}</div>
: <div>Drop files here!</div>
<div
ref={dropRef}
className={
drag ? "filedrop drag" : filename ? "filedrop ready" : "filedrop"
}
>
{filename && !drag ? <div>{filename}</div> : <div>Drop files here!</div>}
</div>
)
}
);
}
```

View File

@ -82,10 +82,10 @@
{
"name": "FileDrop.md",
"title": "FileDrop",
"text": "Renders a file drag and drop component for a single file.\n\nCreate a ref called `dropRef` for this component.\nInitialize `state.drag` and `state.filename` to `false` and `''` respectively.\nThe variables `dragCounter` and `state.drag` are used to determine if a file is being dragged, while `state.filename` is used to store the dropped file's name.\nCreate the `handleDrag`, `handleDragIn`, `handleDragOut` and `handleDrop` methods to handle drag and drop functionality, bind them to the component's context.\nEach of the methods will handle a specific event, the listeners for which are created and removed in `componentDidMount` and `componentWillUnmount` respectively.\n`handleDrag` prevents the browser from opening the dragged file, `handleDragIn` and `handleDragOut` handle the dragged file entering and exiting the component, while `handleDrop` handles the file being dropped and passes it to `this.props.handleDrop`.\nIn the `render()` method, create an appropriately styled `<div>` and use `state.drag` and `state.filename` to determine its contents and style. \nFinally, bind the `ref` of the created `<div>` to `dropRef`.\n\n\n",
"text": "Renders a file drag and drop component for a single file.\n\nCreate a ref called `dropRef` for this component.\nUse the `React.useState()` hook to create the `drag` and `filename` variables, initialized to `false` and `''` respectively.\nThe variables `dragCounter` and `drag` are used to determine if a file is being dragged, while `filename` is used to store the dropped file's name.\n\nCreate the `handleDrag`, `handleDragIn`, `handleDragOut` and `handleDrop` methods to handle drag and drop functionality, bind them to the component's context.\nEach of the methods will handle a specific event, the listeners for which are created and removed in the `React.useEffect()` hook and its attached `cleanup()` method.\n`handleDrag` prevents the browser from opening the dragged file, `handleDragIn` and `handleDragOut` handle the dragged file entering and exiting the component, while `handleDrop` handles the file being dropped and passes it to `props.handleDrop`.\nReturn an appropriately styled `<div>` and use `drag` and `filename` to determine its contents and style. \nFinally, bind the `ref` of the created `<div>` to `dropRef`.\n\n\n",
"codeBlocks": [
"```css\n.filedrop {\n min-height: 120px;\n border: 3px solid #D3D3D3;\n text-align: center;\n font-size: 24px;\n padding: 32px;\n border-radius: 4px;\n}\n\n.filedrop.drag {\n border: 3px dashed #1E90FF;\n}\n\n.filedrop.ready {\n border: 3px solid #32CD32;\n}\n```",
"```jsx\nclass FileDrop extends React.Component {\n constructor(props) {\n super(props);\n this.dropRef = React.createRef();\n this.state = {\n drag: false,\n filename: ''\n }\n this.handleDrag = this.handleDrag.bind(this);\n this.handleDragIn = this.handleDragIn.bind(this);\n this.handleDragOut = this.handleDragOut.bind(this);\n this.handleDrop = this.handleDrop.bind(this);\n }\n\n handleDrag(e) {\n e.preventDefault();\n e.stopPropagation();\n }\n\n handleDragIn(e) {\n e.preventDefault();\n e.stopPropagation();\n this.dragCounter++;\n if (e.dataTransfer.items && e.dataTransfer.items.length > 0) \n this.setState({ drag: true });\n }\n\n handleDragOut(e) {\n e.preventDefault();\n e.stopPropagation();\n this.dragCounter--;\n if (this.dragCounter === 0) \n this.setState({ drag: false });\n }\n\n handleDrop(e) {\n e.preventDefault();\n e.stopPropagation();\n this.setState({ drag: false });\n if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n this.props.handleDrop(e.dataTransfer.files[0]);\n this.setState({ filename : e.dataTransfer.files[0].name});\n e.dataTransfer.clearData();\n this.dragCounter = 0;\n }\n }\n\n componentDidMount() {\n let div = this.dropRef.current;\n div.addEventListener('dragenter', this.handleDragIn);\n div.addEventListener('dragleave', this.handleDragOut);\n div.addEventListener('dragover', this.handleDrag);\n div.addEventListener('drop', this.handleDrop);\n }\n\n componentWillUnmount() {\n let div = this.dropRef.current;\n div.removeEventListener('dragenter', this.handleDragIn);\n div.removeEventListener('dragleave', this.handleDragOut);\n div.removeEventListener('dragover', this.handleDrag);\n div.removeEventListener('drop', this.handleDrop);\n }\n\n render() {\n return (\n <div ref={this.dropRef} className={this.state.drag ? 'filedrop drag' : this.state.filename ? 'filedrop ready' : 'filedrop'}>\n {this.state.filename && !this.state.drag ? \n <div>{this.state.filename}</div>\n : <div>Drop files here!</div>\n }\n </div>\n )\n }\n}\n```",
"```jsx\nfunction FileDrop(props) {\n const [drag, setDrag] = React.useState(false);\n const [filename, setFilename] = React.useState('');\n let dropRef = React.createRef();\n let dragCounter = 0;\n\n const handleDrag = e => {\n e.preventDefault();\n e.stopPropagation();\n };\n\n const handleDragIn = e => {\n e.preventDefault();\n e.stopPropagation();\n dragCounter++;\n if (e.dataTransfer.items && e.dataTransfer.items.length > 0) setDrag(true);\n };\n\n const handleDragOut = e => {\n e.preventDefault();\n e.stopPropagation();\n dragCounter--;\n if (dragCounter === 0) setDrag(false);\n };\n\n const handleDrop = e => {\n e.preventDefault();\n e.stopPropagation();\n setDrag(false);\n if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n props.handleDrop(e.dataTransfer.files[0]);\n setFilename(e.dataTransfer.files[0].name);\n e.dataTransfer.clearData();\n dragCounter = 0;\n }\n };\n\n React.useEffect(() => {\n let div = dropRef.current;\n div.addEventListener(\"dragenter\", handleDragIn);\n div.addEventListener(\"dragleave\", handleDragOut);\n div.addEventListener(\"dragover\", handleDrag);\n div.addEventListener(\"drop\", handleDrop);\n return function cleanup() {\n div.removeEventListener(\"dragenter\", handleDragIn);\n div.removeEventListener(\"dragleave\", handleDragOut);\n div.removeEventListener(\"dragover\", handleDrag);\n div.removeEventListener(\"drop\", handleDrop);\n };\n });\n\n return (\n <div\n ref={dropRef}\n className={\n drag ? \"filedrop drag\" : filename ? \"filedrop ready\" : \"filedrop\"\n }\n >\n {filename && !drag ? <div>{filename}</div> : <div>Drop files here!</div>}\n </div>\n );\n}\n```",
"```jsx\nReactDOM.render(<FileDrop handleDrop={console.log}/>, document.getElementById('root'));\n```"
],
"expertise": 2,

View File

@ -3,12 +3,13 @@
Renders a file drag and drop component for a single file.
Create a ref called `dropRef` for this component.
Initialize `state.drag` and `state.filename` to `false` and `''` respectively.
The variables `dragCounter` and `state.drag` are used to determine if a file is being dragged, while `state.filename` is used to store the dropped file's name.
Use the `React.useState()` hook to create the `drag` and `filename` variables, initialized to `false` and `''` respectively.
The variables `dragCounter` and `drag` are used to determine if a file is being dragged, while `filename` is used to store the dropped file's name.
Create the `handleDrag`, `handleDragIn`, `handleDragOut` and `handleDrop` methods to handle drag and drop functionality, bind them to the component's context.
Each of the methods will handle a specific event, the listeners for which are created and removed in `componentDidMount` and `componentWillUnmount` respectively.
`handleDrag` prevents the browser from opening the dragged file, `handleDragIn` and `handleDragOut` handle the dragged file entering and exiting the component, while `handleDrop` handles the file being dropped and passes it to `this.props.handleDrop`.
In the `render()` method, create an appropriately styled `<div>` and use `state.drag` and `state.filename` to determine its contents and style.
Each of the methods will handle a specific event, the listeners for which are created and removed in the `React.useEffect()` hook and its attached `cleanup()` method.
`handleDrag` prevents the browser from opening the dragged file, `handleDragIn` and `handleDragOut` handle the dragged file entering and exiting the component, while `handleDrop` handles the file being dropped and passes it to `props.handleDrop`.
Return an appropriately styled `<div>` and use `drag` and `filename` to determine its contents and style.
Finally, bind the `ref` of the created `<div>` to `dropRef`.
@ -32,79 +33,67 @@ Finally, bind the `ref` of the created `<div>` to `dropRef`.
```
```jsx
class FileDrop extends React.Component {
constructor(props) {
super(props);
this.dropRef = React.createRef();
this.state = {
drag: false,
filename: ''
}
this.handleDrag = this.handleDrag.bind(this);
this.handleDragIn = this.handleDragIn.bind(this);
this.handleDragOut = this.handleDragOut.bind(this);
this.handleDrop = this.handleDrop.bind(this);
}
function FileDrop(props) {
const [drag, setDrag] = React.useState(false);
const [filename, setFilename] = React.useState('');
let dropRef = React.createRef();
let dragCounter = 0;
handleDrag(e) {
const handleDrag = e => {
e.preventDefault();
e.stopPropagation();
}
};
handleDragIn(e) {
const handleDragIn = e => {
e.preventDefault();
e.stopPropagation();
this.dragCounter++;
if (e.dataTransfer.items && e.dataTransfer.items.length > 0)
this.setState({ drag: true });
}
dragCounter++;
if (e.dataTransfer.items && e.dataTransfer.items.length > 0) setDrag(true);
};
handleDragOut(e) {
const handleDragOut = e => {
e.preventDefault();
e.stopPropagation();
this.dragCounter--;
if (this.dragCounter === 0)
this.setState({ drag: false });
}
dragCounter--;
if (dragCounter === 0) setDrag(false);
};
handleDrop(e) {
const handleDrop = e => {
e.preventDefault();
e.stopPropagation();
this.setState({ drag: false });
setDrag(false);
if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
this.props.handleDrop(e.dataTransfer.files[0]);
this.setState({ filename : e.dataTransfer.files[0].name});
props.handleDrop(e.dataTransfer.files[0]);
setFilename(e.dataTransfer.files[0].name);
e.dataTransfer.clearData();
this.dragCounter = 0;
}
dragCounter = 0;
}
};
componentDidMount() {
let div = this.dropRef.current;
div.addEventListener('dragenter', this.handleDragIn);
div.addEventListener('dragleave', this.handleDragOut);
div.addEventListener('dragover', this.handleDrag);
div.addEventListener('drop', this.handleDrop);
}
React.useEffect(() => {
let div = dropRef.current;
div.addEventListener("dragenter", handleDragIn);
div.addEventListener("dragleave", handleDragOut);
div.addEventListener("dragover", handleDrag);
div.addEventListener("drop", handleDrop);
return function cleanup() {
div.removeEventListener("dragenter", handleDragIn);
div.removeEventListener("dragleave", handleDragOut);
div.removeEventListener("dragover", handleDrag);
div.removeEventListener("drop", handleDrop);
};
});
componentWillUnmount() {
let div = this.dropRef.current;
div.removeEventListener('dragenter', this.handleDragIn);
div.removeEventListener('dragleave', this.handleDragOut);
div.removeEventListener('dragover', this.handleDrag);
div.removeEventListener('drop', this.handleDrop);
}
render() {
return (
<div ref={this.dropRef} className={this.state.drag ? 'filedrop drag' : this.state.filename ? 'filedrop ready' : 'filedrop'}>
{this.state.filename && !this.state.drag ?
<div>{this.state.filename}</div>
: <div>Drop files here!</div>
<div
ref={dropRef}
className={
drag ? "filedrop drag" : filename ? "filedrop ready" : "filedrop"
}
>
{filename && !drag ? <div>{filename}</div> : <div>Drop files here!</div>}
</div>
)
}
);
}
```