用 React + Rails + GraphQL 构建图像上传功能!

最开始

我最近也开始接触React,为了学习的需要

    React + Rails + GraphQL

我正在制作一个个人SPA应用程序!所以,这次我想尝试创建一个图片上传功能!

关于使用的物品,简单作说明。

    • Ruby on Rails (バックエンド)

 

    • React(フロントエンド)

 

    • TypeScript

 

    • GraphQL

 

    Apollo

实施

后端

为了上传图像,需要安装以下的Gem。

# Gemfile
gem 'carrierwave'
gem 'carrierwave-base64' 
    • モデルファイルにアップローダーを指定する記述を追加

以下の記述だけでbase64で渡ってきたデータを画像として保存してくれる…!

# Item.rb
class Item < ApplicationRecord
  mount_base64_uploader :image, ItemImageUploader <- これを追加
end

如果你不了解CarrierWave,请自行搜索了解。

在Resolver中接收参数值并保存

# app/graphql/mutations/create_item.rb
module Mutations
  class CreateItem < Mutations::BaseMutation
    argument :params, InputTypes::Item, required: true <- 引数用のTypeファイル

    field :item, ObjectTypes::Item, null: false

    def resolve(params:)
      item = Item.create!(params.to_h)

      {item: item}

    rescue => e
      GraphQL::ExecutionError.new(e.message)
    end
  end
end

# app/graphql/input_types/item.rb(引数用Typeファイル)
module InputTypes
  class Item < Types::BaseInputObject
    graphql_name 'ItemAttributes'

    argument :image, String, required: false <- 追加
  end
end

前端

创建用于选择图像的表单

    inputタグ追加(type=”file”でファイル選択フォームに)
<input
  name="file"
  type="file"
  accept="image/png"
/>
スクリーンショット 2023-02-25 19.45.56.png

使用useState,在状态中添加管理选择图像的state。

  import { useState } from "react";
  const [image, setImage] = useState<string | undefined>(undefined)

在选择图片时,添加一个函数将图片数据设置到上述的image state中。

使用readAsDataURL函数,将图片转换为base64格式(将图片转换为字符串)!
※ 由于GraphQL只能处理JSON格式的数据,无法处理二进制数据,因此需要转换为字符串!

  const onChangeFile = (e: React.ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files
    if (files && files[0]) {
      const reader = new FileReader()
      reader.readAsDataURL(files[0])
      reader.onload = function() {
        var image: any
        image = reader.result;
        setImage(image); <- image stateに画像をセット
      }
    }
  }
    inputタグで、画像セット時に↑の関数を呼び出して、選択画像をimage stateにセットする
<input
  name="file"
  type="file"
  accept="image/png"
  onChange={onChangeFile} <- 追加
/>
    以下のように、image stateを、imgタグのsrcにセットすると選択中の画像が確認できるかとおもいます!
<img src={image} />
スクリーンショット 2023-02-25 19.59.52.png

只需要将图像数据传递给Mutation的参数即可。

const [createItem] = useCreateItemMutation();
createItem({ variables: { params: { image: image } } });

感谢您阅读本文,并提供实现的一个例子!

广告
将在 10 秒后关闭
bannerAds