20210115のReactに関する記事は8件です。

【React】仮想DOMって何!?

ReactにおけるDOM構築について

ReactはDOMを仮に構築する仕組みを備えており、仮想DOMを設計してからリアルDOMを作成するため、従来のDOMやフレームワークで構築されたDOMに比べると、処理のスピードが速くWebページの表示を高速で切り替えることができます。

DOMについて

DOM(Document Object Model)は、HTMLファイルのソースコードのことではなく、画面を表示するまでに解釈したHTML/CSS/JavaScriptによって構築されたDOM(ツリー)を指します。DOMはChromeやFireFox、Safari、IEなどのブラウザ上で、Webページを描画するために構築されます。

Chromeの開発者ツールのElementsタブでDOMツリーを見てみます(イメージ)。

Chromeの開発者ツールのElementsタブでDOMツリーの例

ここで表示されているものはHTMLのソースコードそのものではなく、ブラウザ上にwebページを描画するために解釈されたHTML/CSS/JavaScriptよって構築されたDOMになります。

DOMツリーの最上階は「Document」で、DocumentとはHTML全体を表しています。

pic_htmltree.gif

出典: JavaScript HTML DOM

DOMはWebページとスクリプトやプログラミング言語を接続するものであり、JavaScriptなどによって、要素の値をダイレクトに操作することができます。

JavaScriptや従来のフレームワーク(jQueryなど)では、スクリプトのロジックから受け取った情報をもとにHTMLを作成し、それを元にブラウザに表示するための描画を行います。

状態が変わるなど情報に変化があった場合は、改めて情報を受け取り直してからDOMを再構築し、それを元に再描画を行って画面を変化させるので表示が遅くなってしまいます。

仮想DOM(VIRTUAL DOM)について

Reactにおける仮想DOMとは、情報を受け取ってもすぐにはブラウザの描画を行わず、まずはバーチャルなDOM(プログラム的に作成された仮のDOM)を構築することを指します。そして、構築された仮想DOMの内容を元にHTMLを作成し、実際のDOM(リアルDOM)に反映させます。

この仮想DOMはリアルDOMに比べ、ページ表示の高速化を実現します。

  • 変更前仮想DOMと変更後DOMの2種類構築
  • コンポーネントのstateが書き換えられる
  • 仮想DOMを再構築
  • 変更前変更後の2つの仮想DOMを比較、差分検出
  • 変更箇所のみリアルDOMに反映

従来のDOM構築の流れとReactで仮想DOMを利用したDOM再構築の流れ

仮想DOMを利用することで、ページ変更前と変更後を仮想DOMを比較、情報が変化した部分だけを素早く見つけ出し、変更差分だけリアルDOMに反映するので、変更が最小限に抑えられるという仕組みです。

無駄のないDOMの操作処理を行うことで、ページ表示の高速化によるパフォーマンス向上を実現します:heart_eyes:

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Scratch Offline Editor for Linuxを作る

ScratchはOffline Editorを提供しているため,オンラインでなくても使うことができます.
Scratch - Scratch Offline Editor
image.png

しかし,上記リンクを見れば分かるとおり,Linux向けがありません.残念...

ところが,ScratchはEditorのGUIをオープンソースで公開しています.
LLK/scratch-gui

これを自分でビルドしてローカルで実行すれば,オフライン版Scratchとして使えそうです.

準備

以下を揃えてください.

  • Node.js
  • npm
  • git
  • 適当なブラウザ(ChromeとかChromiumとかFirefoxとか)

以下はUbuntuでの例です.

Ubuntuでの例

パッケージをインストールします.

Gitをインストールします.

sudo apt install git

次に,以下の記事を参考にしてNode.jsの環境を入れてください(引用させていただきます.ありがとうございます).
Ubuntuに最新のNode.jsを難なくインストールする

いざ

まず,Gitからリポジトリをクローン,依存関係のインストールを行います.結構時間かかるかも.

git clone --depth=1 https://github.com/LLK/scratch-gui.git
cd scratch-gui
npm install

ScratchはReactで作られているので,これでnpm startとすれば起動できますが,起動するたびにコンパイルされるのは少し時間がかかってしまいます.ということで,先にコンパイルしておきます.
結構時間かかります.

npm run-script build

終わると,builds/内にindex.htmlが生成されていると思います.これをChrome等で開き,正常に動作すればオフライン版完成.
image.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

React GoogleMapAPIで地名や住所から緯度経度を取得する方法

はじめに

今回は、地名や住所を入力して緯度と経度の情報を取得する方法をまとめました。
これができると、入力した地名にピンを立てたり、地図が移動したりできるのではないかと思います。
Reactのライブラリreact-geocodeを使用します。
単にマップを表示させたいという方はこちらをご参考ください。
事前にGoogleMapのAPIキーの取得と有効化、GeocodingAPIの有効化をお願い致します。

参考サイト

地名から緯度経度を取得するパターンと緯度経度から地名を取得するパターン両方載っています。
今回はHow to get lat and lng from addressで調べました。
https://www.npmjs.com/package/react-geocode

導入方法

まずはライブラリを利用する準備をします。
react-geocodeの最新バージョンを調べます。

$ npm info react-geocode

結果の一部がこちら

react-geocode@0.2.2 | MIT | deps: 1 | versions: 15
A module to transform a description of a location (i.e. street address, town name, etc.) into geographic coordinates (i.e. latitude and longitude) and vice versa.
https://github.com/shukerullah/react-geocode#readme

今の最新バージョンはreact-geocode@0.2.2でしたので、これをyarn addします。

$ yarn add react-geocode@0.2.2

これでこのプロジェクトでreact-geocodeが使えるようになりました。

地名から緯度経度を取得(コードの中)

まずはライブラリをimport

Geo.js
import Geocode from "react-geocode";

アロー関数の中はこんな感じで書きます。

Geo.js
const Geo = () => {

    Geocode.setApiKey("YOUR_APIKEY");
    Geocode.fromAddress("Eiffel Tower").then(
        response => {
            const { lat, lng } = response.results[0].geometry.location;
            console.log(lat, lng);
        },
        error => {
            console.error(error);
        }
    );
    return (
        <div>
            <h1>map</h1>
        </div>
    )
}

検証モードでconsoleを見ると、エッフェル塔の緯度と経度が確認できるかと思います。
下のdiv要素が無いとreturnするものが無いですというエラーが発生するので、とりあえず適当に入れています。
YOUR_APIKEYのところにご自身の取得したGoogleMapのAPIキーを入力してください。

地名から緯度経度を取得(画面で入力した地名)

先ほどの"Eiffel Tower"の部分を画面上で入力した地名に置き換えたいと思います。
まずはinputタグとbuttonタグで入力する部分を準備します。
先ほどのh1タグの下に

Geo.js
 <h1>map</h1>
 <input type='text'
        onChange={(e) => {
        setPlace(e.target.value)
 }}></input>
 <button onClick={() => {
         PushData();
 }}>search</button>

そして緯度経度を取得するコードの部分を関数に入れてあげます。
ボタンを押したらこの関数が走るように設定します。

Geo.js
const [place, setPlace] = useState('');
    const PushData=()=> {
        Geocode.setApiKey("YOUR_APIKEY");
        Geocode.fromAddress(place).then(
            response => {
                const { lat, lng } = response.results[0].geometry.location;
                console.log(lat, lng);
            },
            error => {
                console.error(error);
            }
        );
    }

入力欄が変更されるとsetPlace関数が動いて、placeに入力した値が入ります。
searchボタンが押されると入力した地名の緯度と経度が取得できます。

あっ、useStateのimportもお忘れなく!

Geo.js
import React, { useState } from 'react';

終わりに

今回は入力した地名から緯度と経度を取得するまでをご紹介しました。
次の投稿で取得した緯度経度を用いて、Googleマップにピンの立て方をまとめてみたいと思います。
firebaseも使います。
最後まで読んでいただきありがとうございます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

React(TypeScript)のlabelタグにnameやvalue属性の代替えを属性をいれる

結論としてカスタム属性を使います。

JSX上でinputタグ(type="radio")とlabelの擬似要素を組み合わせた際に実際にクリックされる方であるlabelタグの属性にnameやvalueを使えずつまづいたので代替え方法のTIPSです。

背景

ご存知のようにinput + labelのスタイル制御はJSを使わずに選択されたラベルのスタイルを変更するHTML/CSSでこれまで使われきた手法です。

わざわざReactでこのテクニックを使ってしまったところlabelクリック時に状態を保存したいのですがlabelタグにnameやvalueといった属性は使えないためlabeタグに必要な情報を埋め込めなくなりました。

素直にJSオンリーでスタイル制御すべきだった...
nameやvalueをlabelタグへそのまま使うと当然のようにそんな属性の型はねえぞと怒られる。

Type '{ children: string; onClick: (e: MouseEvent<HTMLLabelElement, MouseEvent>) => void; value: string | number; id: string; htmlFor: string; }' is not assignable to type 'DetailedHTMLProps<LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>'.
  Property 'value' does not exist on type 'DetailedHTMLProps<LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>'.ts(2322)

もうCSSでスタイルを当ててしまったあとだし作り変えるための優先順位はそこまで高くないしということでこのままlabelで使えるようにしました。同じような人はどうぞ。

解決策:カスタム属性を使う

といっても解決策は単純でnameやvalueに変わる属性を付与します。

<label data-{任意の名前} >Hello 沼!</label>

というようにカスタム属性を使います。

sample.tsx
<label onClick={e => handleClickChange(e)} data-name={name} data-value={value} 
 htmlFor={idName} >Hello !</label>

引っ張る際には e.currentTarget.dataset.{任意のカスタムデータ名} で引っ張れます。接頭辞のdata-は不要ですが。
そしてTypeScriptとしてアサーションを使うのは御行儀がよくないのですが下のような形で引っ張ってこれました。

sample.tsx
  const handleClickChange = (e: MouseEvent): void => { 
    const name = (e.currentTarget as HTMLInputElement).dataset.name as string;
    const value = (e.currentTarget as HTMLInputElement).dataset.value;
    setProfile(currentValue => ({
      ...currentValue,
      [name]: value
    }));
  }

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

React(TypeScript)のlabelタグにnameやvalue属性の代替え属性をいれる

結論としてカスタム属性を使います。

JSX上でinputタグ(type="radio")とlabelの擬似要素を組み合わせた際に実際にクリックされる方であるlabelタグの属性にnameやvalueを使えずつまづいたので代替え方法のTIPSです。

背景

ご存知のようにinput + labelのスタイル制御はJSを使わずに選択されたラベルのスタイルを変更するHTML/CSSでこれまで使われきた手法です。

わざわざReactでこのテクニックを使ってしまったところlabelクリック時に状態を保存したいのですがlabelタグにnameやvalueといった属性は使えないためlabeタグに必要な情報を埋め込めなくなりました。

素直にJSオンリーでスタイル制御すべきだった...
nameやvalueをlabelタグへそのまま使うと当然のようにそんな属性の型はねえぞと怒られる。

Type '{ children: string; onClick: (e: MouseEvent<HTMLLabelElement, MouseEvent>) => void; value: string | number; id: string; htmlFor: string; }' is not assignable to type 'DetailedHTMLProps<LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>'.
  Property 'value' does not exist on type 'DetailedHTMLProps<LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>'.ts(2322)

もうCSSでスタイルを当ててしまったあとだし作り変えるための優先順位はそこまで高くないしということでこのままlabelで使えるようにしました。同じような人はどうぞ。

解決策:カスタム属性を使う

といっても解決策は単純でnameやvalueに変わる属性を付与します。

<label data-{任意の名前} >Hello 沼!</label>

というようにカスタム属性を使います。

sample.tsx
<label onClick={e => handleClickChange(e)} data-name={name} data-value={value} 
 htmlFor={idName} >Hello !</label>

引っ張る際には e.currentTarget.dataset.{任意のカスタムデータ名} で引っ張れます。接頭辞のdata-は不要ですが。
そしてTypeScriptとしてアサーションを使うのは御行儀がよくないのですが下のような形で引っ張ってこれました。

sample.tsx
  const handleClickChange = (e: MouseEvent): void => { 
    const name = (e.currentTarget as HTMLInputElement).dataset.name as string;
    const value = (e.currentTarget as HTMLInputElement).dataset.value;
    setProfile(currentValue => ({
      ...currentValue,
      [name]: value
    }));
  }

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Firebaseにデプロイするまで

Firebaseの設定

Firebaseでプロジェクトを立ち上げる

  1. ブラウザでFirebaseのコンソール(https://console.firebase.google.com/u/0/?hl=ja) へアクセスし、Googleアカウントでログインする
  2. 指定のプロジェクトを追加をクリックする
  3. アルファベットの適当なプロジェクト名を設定する
  4. Googleアナリティクスを有効にして続行する
  5. アナリティクスのアカウントを作成してプロジェクトを作成する

プロジェクトの初期設定を行う

  1. プロジェクト画面で、web設定(</>ボタン)をクリックする
  2. アプリのニックネーム(上のプロジェクト名と同様で良い)を設定して次へをクリックする
  3. Firebase SDKの追加で、次へをクリックする
  4. Firebase CLIのインストールで、表示されたコマンド(npm install -g firebase-tools)をPCのコマンドラインで実行する ※過去に実行したことがある場合は不要
  5. Firebase Hosting Deploy次へをクリックする

プロジェクトの設定を行う

  1. プロジェクト画面の右上の設定ボタン(左上の歯車ボタン)をクリックする
  2. リソースロケーションで、asia-notheast1を選択し、完了をクリックする ※ここは一度設定すると変更不可のため注意
  3. 左のCloud Firestoreをクリックする
  4. データベースの作成をクリックする
  5. 本番環境の開始を選択して続行する
  6. ロケーションの選択は変更せず完了をクリックする

ターミナルでの設定

ローカルのディレクトリとFirebaseを紐付ける

  1. ローカルPCにアプリを作るディレクトリを作る
  2. コマンドラインで作成したディレクトリに移動する
  3. コマンドラインで、firebase loginと入力してEnterする
  4. ブラウザ上でGoogleアカウントを選択する画面に移動したら、上でしていたGoogleアカウントを選択して許可をする
  5. コマンドラインで、firebase initと入力してEnterする
  6. firebaseで使用するサービスが表示されるため、矢印キーとスペースキーで下記を選択してEnterする
    • Firestore
    • Functions
    • Hosting
    • Storage
  7. 使用するプロジェクトとして、新規プロジェクトor既存のプロジェクトを聞かれるため、既存のプロジェクト Use an existing projectを選択してEnterする
  8. ブラウザのFirebase画面で生成したプロジェクト一覧が表示されるため、上で生成したプロジェクト名を選択してEnterする
  9. Firestoreで使用するルール、Firestoreのindexを聞かれるので、デフォルトの設定のまま(何も入力せず)、Enterする
  10. 使用する言語としてJavaScriptTypeScriptの選択が表示されるため、得意な言語を選択する
  11. ESLintを用いるか、依存関係のあるパッケージのインストールを聞かれるため、どちらもデフォルトの設定(ESLintは使用しない、パッケージはインストールする)のままEnterする
  12. publicディレクトリを聞かれるため、buildと入力してEnterする(デフォルトではpublic)
  13. SinglePageAppとして設定するかを聞かれるので、yesと入力してEnterする(デフォルトではNo) これでFirebaseとの紐付けは完了

必要なパッケージの追加

開発に必要と思われるパッケージをnpmインストールする。
コマンドラインで、下記のコマンドを実行する(XXXXX, YYYYY, ZZZZZに必要なパッケージ名を記入)
npm install --save XXXXX YYYYY ZZZZZ

開発におすすめのパッケージ

パッケージ名 内容
@material-ui/core material-uiの基本
@material-ui/icons material-uiのアイコン
@material-ui/styles material-uiのスタイル
connected-react-router Reactルータのパッケージ
firebase Firebase
history URL遷移の記録
react-redux reduxのパッケージ
react-router ルーティングのパッケージ
redux redux
redux-actions reduxのactions
redux-logger reduxのstateの変化のログ
redux-thunk reduxの非同期処理を待つ
reselect

上記を実行すると、ディレクトリ内のpackage.jsonに上記が追加される

デプロイの実行

デプロイして公開する

  1. コマンドライン上でnpm run buildと入力して実行し、ビルドを行う(公開できるようにファイルを変換する)
  2. firebase deployを実行する

firebaseのプランを無料から従量制に変更しておかないとHTTP ERROR: 400*と表示される
3. コマンドライン上に表示されたURLをコピーしてブラウザで実行すると、生成した画面が生成される

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

未経験エンジニアが3か月でアプリをリリースした話

Webアプリをリリースしました

 この度、「coma4」というwebアプリを開発しました。4コマ漫画の配信サイトです。
誰でも投稿することが出来ますので、気軽に作品を投稿してみてください。投稿した作品にいいね、お気に入り、コメントをすることができます。詳しい概要は、下記リンクよりcoma4のサポートページをご覧ください。
 差し支えなければ本記事の最後にございますアンケートにご協力願います。

https://www.coma4.com/
↑上記リンクよりアクセスできます

トップページ
投稿がタイムラインで一覧表示され、クリックすると視聴することができます。
image.png

投稿画面(coma4 Studio)
4コマ漫画にBGM、効果音をつけて動画に書き出す編集スタジオです。
アップロード画面.PNG

サービス構成

サービス構成図.PNG

制作動機

 近年、SNSなど個人が発信できる場は豊富にある。その陰で、発信しても見てもらえない人が多いのでないかと考えた。そこで、今日、クリエイターになりたいがなれない人を4コマ漫画でクリエイターにすることにした。

Webアプリを作る前のスキル

・JavaServlet
・C言語でLEGOマインドストームの制御
・Kotlinでandroidアプリ開発
・HTML5 , CSS3
・Python3

実装

■開発環境
エディタ:VSCode
コード管理:Git , GitHub

■データベース
Postgres , Cloudinary(無料枠)

■音楽素材
魔王魂(https://maoudamashii.jokersounds.com/)

■想定ブラウザ
Google Chrome , Safari

■対応デバイス
PC , タブレット , スマートフォン

■ライブラリ
フロントエンド:Bootstrap , Axios , toastr , bootbox
バックエンド:gunicorn , whitenoise , openCV , MoviePy ...etc

■リリース
インフラ:Heroku(無料枠)
SSL:Cloudflare(無料枠)
Mail server:Mailgun(無料枠)

システム構成

システム構成1.png

アンケートのお願い

最後に、「coma4」をより良いものとするためアンケートのご協力をお願いします。
https://www.coma4.com/ のTopページの下部よりアンケートのご回答を宜しくお願いいたします。
(※1) アカウント登録をしなくても投稿を見ていただければ、アンケートに回答できます。
(※2) アンケート回答時間は30秒~3分程度です。また、個人情報の入力は一切なく、匿名での回答となります。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ReactをGitHubへ公開する手順

vsCodeターミナルにて

npm install gh-pages --save-dev

Reactのフォルダを開いてpacage.jsonへ移動
一番上に

"homepage" : "http://[GitHubの名前].github.io/[リポジトリ名]",

scriptに

"predeploy": "npm run build",
"deploy": "gh-pages -d build",

を追加

ターミナルにて

git init 
add git remote add origin [リポジトリSSH]
git status
git add .

addの後ろに[.]を入れることで全てを指定

git commit -m "コメント"
npm run deploy
git -u origin main

で完了

参考url
https://youtu.be/F8s4Ng-re0E

個人的にリモートの紐付けに手間取った
紐付けを行おうとすると

fatal: remote origin already exists. 

とメッセージが出て先に進めない
解決策として

git remote rm origin

でoriginを消去すればいけた

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む