React.jsでの画像アップロードからプレビュー表示
はじめに
React.jsを使って、画像アップロードからプレビュー表示までを作成していきます。
Reactとは
環境
Windows 10
Node.js 8.5.5
React.js
フォルダ構成
react
├── node_modules
├── public
│ └── index.html
├── src
│ ├── index.js
│ └── index.css
└── package.json
レイアウト作成
まずは、react/src/index.js
の中身を次のようにします。
import { createRoot } from 'react-dom/client'
import React, { Component } from 'react'
export default class App extends React.Component {
render() {
return (
<div>
<input type="file" accept="image/*" />
<div>
<img src="" />
</div>
</div>
)
}
}
const root = createRoot(document.getElementById('app'))
root.render(<App />)
<input type="file">
の下にプレビュー表示できる要素を設置します。
呼出側のHTMLreact/public/index.html
の記載は以下です。
<html>
<body>
<div id="app"></div>
</body>
</html>
React.jsの作成
次にReact.js
部分です。
コンストラクタで画像を格納する変数の準備
App
が呼び出された直後にthis.state
へ変数名imageData
を作ります。
ここには<input type="file">
で選択された画像データが入ってきます。
constructor(props) {
super(props)
this.state = {
imageData: null
}
}
画像選択時のイベントを作成
<input type="file">
にonChange
イベントを設定します。
その際、onFileChange()
にイベント変数を渡します。
return (
<div>
<input type="file" accept="image/*" onChange={
(e) => {
this.onFileChange(e)
}
} />
<div>
<img src="" />
</div>
</div>
)
イベント変数を受け取るonFileChange()
は以下で作成します。
画像が選択されていた場合、FileReader()
で画像データを取得しています。
取得した画像データは、先ほど記載したconstructor
で設定したimageData
の変数に格納しています。
もし、キャンセルされた場合は、imageData
へnull
を渡し、初期化をしています。
onFileChange(e) {
const files = e.target.files
if (files.length > 0) {
var file = files[0]
var reader = new FileReader()
reader.onload = (e) => {
this.setState({ imageData: e.target.result })
};
reader.readAsDataURL(file)
} else {
this.setState({ imageData: null })
}
}
プレビュー表示箇所の作成
preview
変数に画像要素を格納することで、画像が選択されていない場合に何も表示せず、画像が選択された場合にのみ、プレビュー要素を表示することができます。
render() {
const imageData = this.state.imageData
let preview = ''
if (imageData != null) {
preview = (
<div>
<img src={imageData}/>
</div>
)
}
return (
<div>
<input type="file" accept="image/*" onChange={
(e) => {
this.onFileChange(e)
}
} />
{preview}
</div>
)
}
index.js
最終的なimport { createRoot } from 'react-dom/client'
import React, { Component } from 'react'
export default class App extends React.Component {
constructor(props) {
super(props)
this.state = {
imageData: null
}
}
onFileChange(e) {
const files = e.target.files
if (files.length > 0) {
var file = files[0]
var reader = new FileReader()
reader.onload = (e) => {
this.setState({ imageData: e.target.result })
};
reader.readAsDataURL(file)
} else {
this.setState({ imageData: null })
}
}
render() {
const imageData = this.state.imageData
let preview = ''
if (imageData != null) {
preview = (
<div>
<img src={imageData}/>
</div>
)
}
return (
<div>
<input type="file" accept="image/*" onChange={
(e) => {
this.onFileChange(e)
}
} />
{preview}
</div>
)
}
}
const root = createRoot(document.getElementById('app'))
root.render(<App />)
実行結果
おわりに
React.jsはパーツごとの実装に長けているので、他にも応用できれば、可読性の高い良いプロジェクトが作れそうな感じはしました。
(書き方については慣れが必要かもしれません。)
以上、React.jsでの画像アップロードからプレビュー表示までの実装でした。
Discussion