diff --git a/README.md b/README.md index 39e3adc24..c1b257ad1 100644 --- a/README.md +++ b/README.md @@ -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 `
` 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 `
` and use `drag` and `filename` to determine its contents and style. Finally, bind the `ref` of the created `
` to `dropRef`. @@ -743,79 +744,67 @@ Finally, bind the `ref` of the created `
` 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 ( -
- {this.state.filename && !this.state.drag ? -
{this.state.filename}
- :
Drop files here!
- } -
- ) - } + return ( +
+ {filename && !drag ?
{filename}
:
Drop files here!
} +
+ ); } ``` diff --git a/data/snippet_data.json b/data/snippet_data.json index 42be599d0..fdc493f20 100644 --- a/data/snippet_data.json +++ b/data/snippet_data.json @@ -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 `
` and use `state.drag` and `state.filename` to determine its contents and style. \nFinally, bind the `ref` of the created `
` 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 `
` and use `drag` and `filename` to determine its contents and style. \nFinally, bind the `ref` of the created `
` 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
\n {this.state.filename && !this.state.drag ? \n
{this.state.filename}
\n :
Drop files here!
\n }\n
\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 \n {filename && !drag ?
{filename}
:
Drop files here!
}\n
\n );\n}\n```", "```jsx\nReactDOM.render(, document.getElementById('root'));\n```" ], "expertise": 2, diff --git a/snippets/FileDrop.md b/snippets/FileDrop.md index c64075fee..7fefbb103 100644 --- a/snippets/FileDrop.md +++ b/snippets/FileDrop.md @@ -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 `
` 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 `
` and use `drag` and `filename` to determine its contents and style. Finally, bind the `ref` of the created `
` to `dropRef`. @@ -32,79 +33,67 @@ Finally, bind the `ref` of the created `
` 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 ( -
- {this.state.filename && !this.state.drag ? -
{this.state.filename}
- :
Drop files here!
- } -
- ) - } + return ( +
+ {filename && !drag ?
{filename}
:
Drop files here!
} +
+ ); } ```