天天看点

如何用 React 完成图片上传功能?

<b>本文讲的是如何用 React 完成图片上传功能?,</b>

<b></b>

对于 web 开发者来说,让用户能够上传图片是一件很常见的事情。一开始可能看起来小菜一碟,但是当真正创建一个图片上传组件的时候,还是有些问题需要去考虑的。这里有一些注意事项:

允许什么类型的图片上传?

需要多大的图片? 这对性能有何影响?

图片长宽比例应该是多少?

如何管理图片? 能扑捉到不良图片吗?

图片存储在哪? 如何运维?

这是我们将要构建的应用的一个小样品。

如何用 React 完成图片上传功能?

我用到了下面三个工具:

Cloudinary 是一个可以为图片提供存储、操作、管理、提供功能的云服务。我选择使用 Cloudinary 是因为它提供的免费账户包含了所有我所需要的功能。你至少需要一个免费帐户才能开始。

假如说你想裁剪,调整大小并给上传的图片增加滤镜。Cloudinary 有个_转换_的概念,和修改图片功能链接在一块的,不管你需不需要。一旦上传,就会转换、修改然后存储新的图片。

在 Cloudinary 控制面板中,找到 Settings &gt; Upload,然后选择 “Upload presets” 下方 的 “Add upload preset”。

如何用 React 完成图片上传功能?

下一步,将 “Mode” 改成 “Unsigned”。这是必须的,然后你就可以不需要使用服务器端语言来处理私钥也能直接上传到 Cloudinary 了。

如何用 React 完成图片上传功能?

在 “Incoming Transformations” 部分选择 “Edit” 可以添加任何转换。 你可以裁剪、调整大小、改变质量、旋转、滤镜等等。保存预设,这就行了!你现在有地方上传、处理、存储图片了,能够为你的应用程序提供图片服务了。注意预设名称,我们稍后将用到它。让我们进入代码部分吧。

首先,安装依赖。在命令行中输入下面的命令,运行:

然后在你的组件中导入 <code>React</code>、 <code>react-dropzone</code> 和 <code>superagent</code>。我使用 ES6 <code>import</code> 语法。

我们稍后会用到 <code>superagent</code>。现在,在你的组件 render 方法中包含一个 <code>react-dropzone</code> 实例。

以下是这个组件的一些概要:

<code>multiple={false}</code> 同一时间只允许一个图片上传。

<code>accept="image/*"</code> 允许任何类型的图片。你可以明确的限制文件类型,只允许某些类型可以上传, 例如<code>accept="image/jpg,image/png"</code>。

<code>onDrop</code> 是一个方法,当图片被上传的时候触发。

现在,让我们设置当上传一个图像时,做某些事情的方法。

首先,为两条重要的上传信息设置一个 <code>const</code> 。

上传预设 ID (当你创建了上传预设时自动生成)

你的 Cloudinary 上传 URL

然后,增加一条记录到组件初始化 state (使用 <code>this.setState</code>);我给这个属性起了个名字 <code>uploadedFileCloudinaryUrl</code>。最终,这将存放一个上传成功后由 Cloudinary 生成的图片 URL。我们稍后会用到这条 state。

<code>react-dropzone</code> 文档说它总是返回一个上传文件的数组,所以我们将该数组传递给 <code>onImageDrop</code> 方法的 <code>files</code> 参数。我们设置了一次只能传一张图片,所以图片总是在数组的第一个位置。

在 <code>.end</code> 回调中,打印所有返回错误的同时,最好也告诉用户出现了一个错误。

接下来,我们接收到的响应中包含一个 URL,检查下它是不是一个空字符串。这就是图片被上传,处理后 Cloudinary 生成的一个 URL。举个例子,如果一个用户正在编辑他的资料,上传了一张图片,你可以将 Cloudinary 返回的新的图片 URL 保存到你的数据库中。

我们目前写的代码,支持用户拖拽一张图片,组件将图片发送到 Cloudinary,然后收到一个给我们用的转换后的图片 URL。

组件最后一部分是一个 <code>div</code>,可以预览上传后的图片。

如果 <code>uploadedFileCloudinaryUrl</code> state 是一个空字符串,三元运算符将输出 <code>null</code> (什么都没有)。回想下,组件的<code>uploadedFileCloudinaryUrl</code> state 默认是一个空字符串;这就意味着组件渲染时,这个 <code>div</code> 将是空的。

然而,当 Cloudinary 返回一个 URL,state 不再是空字符串,因为我们在 <code>handleImageUpload</code> 更新了 state。此时,该组件将重新渲染,显示上传的文件名称和变换后的图像的预览。

This is just the groundwork for an image upload component. There are plenty of additional features you could add, like:

这只是为图片上传组件做的准备工作。有很多可以添加的附加功能,比如:

允许多图片上传

清除上传的图片

如果因为某些原因上传失败,展示错误

使用移动设备相机作为上传源

目前为止,这些设置已经满足我工作的需求了。硬编码上传预设不是完美的,但我还没有碰到任何问题。

<b>原文发布时间为:2016年08月21日</b>

<b>本文来自云栖社区合作伙伴掘金,了解相关信息可以关注掘金网站。</b>

继续阅读