让我来介绍一下实现这个React图片上传组件的完整过程和代码示例。
概述
React是一个流行的JavaScript库,用于开发用户界面。本方案提供了一种基于Node环境使用React实现图片上传的方式。在实现过程中,我们将使用以下技术和库:
- React:使用React构建用户界面组件
- React Dropzone:使用React Dropzone库实现文件拖拽和文件上传
- Node.js:使用Node.js实现服务器接口和上传功能
准备工作
在使用本方案之前,请确保您已经安装了以下工具和库:
- Node.js v10.x或更高版本
- npm 或 yarn 包管理器
在准备好了Node.js和npm或yarn之后,我们需要新建一个React项目。可以使用create-react-app
CLI实用程序快速创建一个新的React应用程序。只需使用以下命令即可:
npx create-react-app react-image-uploader
这将在当前目录下创建一个名为react-image-uploader
的新React项目。
在项目目录中,在前端接口(端口3000)以外,我们还需要在本地开发服务器(端口3001)上运行Node.js后端。 这可以通过安装和运行Express.js服务器程序实现。
首先,在项目目录中打开终端或命令提示符,然后运行以下命令安装Express:
npm install express
当安装完成后,我们可以创建一个名为server.js
的Node.js文件。这是我们的服务端代码。
实现方法
接下来,让我们来实现React图片上传组件的代码。在src
文件夹下创建一个名为ImageUploader.js
的文件。并添加以下代码:
import React, { Component } from 'react';
import Dropzone from 'react-dropzone';
class ImageUploader extends Component {
state = {
files: []
};
handleDrop = acceptedFiles => {
this.setState({
files: acceptedFiles
});
};
handleSubmit = event => {
event.preventDefault();
const formData = new FormData();
formData.append('file', this.state.files[0]);
fetch('http://localhost:3001/api/upload', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
console.log(data);
})
.catch(error => {
console.error(error);
});
};
render() {
return (
<form onSubmit={this.handleSubmit}>
<Dropzone onDrop={this.handleDrop}>
{({ getRootProps, getInputProps }) => (
<div {...getRootProps()}>
<input {...getInputProps()} />
<p>Drag and drop a file here, or click to select a file</p>
</div>
)}
</Dropzone>
{this.state.files.length > 0 && (
<div>
<h5>Selected file:</h5>
<ul>
{this.state.files.map(file => (
<li key={file.name}>
{file.name} - {file.size} bytes
</li>
))}
</ul>
<button>Upload</button>
</div>
)}
</form>
);
}
}
export default ImageUploader;
在这段代码中,我们首先导入 React 和这个文件需要依赖的其他库。在组件的构造函数中,我们将状态初始化为空文件数组。我们定义了handleDrop
方法,该方法监听文件拖放事件并将文件添加到组件的状态中。
handleSubmit
方法将文件上传到服务器。在该方法中,我们首先使用FormData API
创建一个新的FormData对象。然后,我们将当前选定的文件添加到FormData
中,为这个对象起一个名为“file”的字段。接下来,我们使用Fetch API发送POST请求到服务器程序,在该请求中,我们将FormData对象作为请求体提交给服务器。最后,我们解析服务器响应,将其打印到控制台中。
在render
方法中,我们在Dropzone
组件中显示拖放区域和上传按钮。一旦用户选择了一个或多个文件并将它们拖到区域内,handleDrop
方法将调用并更新组件的状态。当有上传文件时,我们会在页面上显示选定的文件的名称和大小,以及一个Upload
按钮。在单击该按钮时,将调用handleSubmit
方法并将文件上传到服务器。
接下来我们创建后端服务。在项目根目录下创建一个名为server.js
的文件。并添加以下代码:
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const app = express();
const PORT = 3001;
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors());
app.post('/api/upload', (req, res) => {
const file = req.files.file;
file.mv(`${__dirname}/public/images/${file.name}`, err => {
if (err) {
console.error(err);
return res.status(500).send(err);
}
res.json({ fileName: file.name, filePath: `/images/${file.name}` });
});
});
app.listen(PORT, () =>
console.log(`Server running at: http://localhost:${PORT}`)
);
在该server.js
文件中,我们首先导入了Express.js、body-parser、cors和其他相关库。然后,我们创建一个Express应用程序,并在端口3001上启动服务器。
我们使用app.post()方法,为上传文件的POST请求定义了路由。该路由检索从客户端发送的文件(客户端会以FormData对象的方式发送请求)。通过使用req.files.file
属性,我们获取客户端请求中的上传文件。在这里,req.files.file
中file
是前端上传时的文件名, 但是该属性需要依赖于中间件的支持。对于本文示例,我们使用了express-fileupload
中间件,它将请求体中的文件解析为req.files属性。为了简化本文示例,我们不再对详细使用该中间件提供说明。
最后,我们将上传的文件存储到public/images
文件夹下,并向客户端发送JSON响应,携带上传文件的名称和路径。该路径可以用于在客户端预览已上传的图像。
示例
为了更好地理解该方案,以下是两个使用示例:
示例一:上传单个图片
先启动 Node 服务,打开终端,进入 server 文件夹, 在本机运行文件 server.js
, 作为 node web 服务器。
切换到 react-image-uploader 项目根目录,启动 React 服务,运行以下命令:
npm start
运行完成后,打开浏览器,访问 http://localhost:3000/。在该网页中,你会看到一个文件上传控件。将需要上传的图片拖动到文件上传控件区域,或者点击添加文件按钮弹出对话框选择需要上传的图片后点击上传。
上传成功后,页面会显示上传的文件名及大小,并有一个预览链接;
示例二:上传多个文件
再次启动 React 和 Node 服务器,进入 react-image-uploader 项目根目录,打开 ImageUploader.js 文件:
import React, { Component } from 'react';
import Dropzone from 'react-dropzone';
class ImageUploader extends Component {
state = {
files: []
};
handleDrop = acceptedFiles => {
this.setState({
files: acceptedFiles
});
};
handleSubmit = event => {
event.preventDefault();
const formData = new FormData();
this.state.files.forEach((file, i) => {
formData.append('file' + i, file);
});
fetch('http://localhost:3001/api/upload', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
console.log(data);
})
.catch(error => {
console.error(error);
});
};
render() {
return (
<form onSubmit={this.handleSubmit}>
<Dropzone onDrop={this.handleDrop}>
{({ getRootProps, getInputProps }) => (
<div {...getRootProps()}>
<input {...getInputProps()} />
<p>Drag and drop some files here, or click to select files</p>
</div>
)}
</Dropzone>
{this.state.files.length > 0 && (
<div>
<h5>Selected files:</h5>
<ul>
{this.state.files.map(file => (
<li key={file.name}>
{file.name} - {file.size} bytes
</li>
))}
</ul>
<button>Upload</button>
</div>
)}
</form>
);
}
}
export default ImageUploader;
说明:在代码示例2中,在ImageUploader
组件的handleSubmit
方法中,我们使用了forEach
方法来迭代所有被选中的文件,然后将它们添加到FormData中,每个文件添加的字段名都不相同,这里存在随机的情况;当上传多个文件时,客户端会向服务器端发送一个包含所有文件的FormData对象,服务器端需要对所有文件进行并发处理,并将它们保存在本地磁盘上。
运行该示例后,资源管理器中存储上传文件的文件夹中会出现多个文件。
结论
在本方案中,我们使用了React Dropzone和fetch API上传图片,同时也使用了Node.js作为后端框架,以实现在本地实现文件上传的功能。你也可以尝试在其他Web框架中使用类似的技术。
祝成功!
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:基于Node的React图片上传组件实现实例代码 - Python技术站