20201130のReactに関する記事は14件です。

(初心者向け)Reactをざっくり理解する

まえがき

最近エンジニアとして就職しまして、
Reactとか触っているのですが難しいなーって思う瞬間がとても多い。。

こちらの記事はReactを勉強する前の自分が、あったらいいなと思うようなことを書いていきます。

対象となる人

この記事では以下のような方達を対象に書いています

  • Reactって何?
  • HTMLとか少し触っただけ
  • でもJavaScriptはあんまわからない

そもそもReactとは?

  • Angular,Vueに並ぶ、SPA(Single Page Application)フレームワークの御三家の1つ
  • Facebook社が作ってる
  • めっちゃ人気

Reactの考え方

  • JSXかJSの中でHTMLを書く。(JSにHTMLっぽい記述をする感覚は、最初は違和感があるかも)
  • コンポーネント(Component):一言でいうと部品。ボタンとか。
  • Atomicデザイン:原子的な部品を作ろうという考え方。役割を最小限にして使いまわせるようにする。Reactで当てはめると、それ以上分解不可能なComponentを作ろう。となる。

参考記事
https://qiita.com/fiftie/items/37b2212739b29f3e79cc

コンポーネントについて

昔はReactのComponentクラスを継承して作るのが一般的だった

qiita.js
class Welcome extends React.Component{
 render(){
  return <h1>Hello,{this.props.name}</h1>
 }
}

今はfunctional component(関数コンポーネントとも)と呼ばれる、Componentを関数として定義することが一般的になりつつある

qiita.js
function Welcome (props) {
 return <h1>Hello,{props.name}</h1>
}

stateについて

  • stateとは状態を管理するための概念。Component内限定の変数みたいな感じ。
  • 大きな特徴は、これが更新されるとそのComponentが再描画されること。

サーバーから取得したあるデータAを、ある要素Xに表示しないといけないとする。
そのとき、要素XにAを表示する、ということを指定さえしておけば、要素Xを捕捉してAを追加して...みたいなことをしないですむ。

propsについて

  • propsとは別のComponentから受け渡されてきた値。
  • ここでは、「props」という名前のpropsに、変数valueを渡している。
  • ChildComponentは「props」を使って何かする。
  • propsが更新されても、そのComponentは再描画される。propsにstateを指定することもできる。
qiita.js
<Child props={value} />

props drillingについて

例えば以下のような構成があるとします。
そして、ComponentAで持っているデータをComponentDに渡したいとします。
qiita.jpg
この時、以下のようなことが発生してしまう。。
props_drilling.jpg
これはめっちゃ不毛:frowning2:
これがprops drilling問題・・。

Reduxでこれを解決する!

Storeと呼ばれるところに値を格納することで、どのコンポーネントでも使うことができる!
reduxImage.jpg

終わりに

かなりざっくりReactについて書いてみました。
参考になれば嬉しいです!

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

【TypeScript】ObjectのKeyに変数でアクセスする

1. はじめに

こんにちは!みなさま楽しいプログラミンライフをお過ごしでしょうか?
最近TypeScriptでのReact開発を勉強しています。

ObjectのKeyに変数でアクセスしようとしたときに、
型付けのところでハマったポイントがあったので、備忘録として残しておきたいと思います。

Version
node.js 14.12.0
yarn 1.22.7
TypeScript 3.8.3

2. やりたいこと

以下のような、
object2のcategoryのvalueと、object1のkeyが一致するvalueの配列に、object2をまるっとpushしたい。object3のようになるイメージ。

const object1 = {
  category1: [],
  category2: []
}

const object2 = {
  id: 1,
  title: "nazeudon",
  category: "category1",
}

const object3 = {
  category1: [
    {
      id: 1,
      title: "nazeudon",
      category: "category1",
    },
  ],
  category2: []
}

3. JavaScriptだとこう書ける

とてもシンプル。まさに。Simple is the Best.

const cat = object2.category;
object1[cat].push(object2);

4. ハマったポイント

同じことをTypeScriptでやろうとすると。。。

const cat = object2.category;
object1[cat].push(object2);

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ category1: never[]; category2: never[]; }'.
No index signature with a parameter of type 'string' was found on type '{ category1: never[]; category2: never[]; }'.(7053)

要素は暗黙のうちに 'any' 型を持っています。なぜなら、型 'string' の式は型 '{ category1: never[]; category2: never[]; }' をインデックス化するために使用できないからです。
type '{ category1: never[]; category2: never[]; }' には、型 'string' のパラメータを持つインデックスシグネチャが見つかりませんでした。

そりゃ、TypeScriptだからね。型付けしろと言うわけですよね!
interfaceで型付けしてやって〜、でも。。。

interface OBJECT1 {
  category1: OBJECT2[]
  category2: OBJECT2[]
}

interface OBJECT2 {
  id: number
  title: string
  category: string
}

const object1: OBJECT1 = {
  category1: [],
  category2: []
}

const object2: OBJECT2 = {
  id: 1,
  title: "nazeudon",
  category: "category1",
}

const cat = object2.category;
object1[cat].push(object2);

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'OBJECT1'.
No index signature with a parameter of type 'string' was found on type 'OBJECT1'.(7053)

要素は暗黙のうちに 'any' 型を持っていますが、それは 'string' 型の表現が型 'OBJECT1' のインデックスに使用できないからです。
型 'OBJECT1' の型 'string' のパラメータを持つインデックス・シグネチャは見つかりませんでした。

おっと、これでもダメなのね。OBJECT1のインデックスにString型を指定できないと言われています。

ってことで、この解決に小一時間費やしたので、解決策を残しておきます。

5. TypeScriptでの書き方(例)

const cat: keyof OBJECT1 = object2.category as keyof OBJECT1;
object1[cat].push(object2);

こんな感じで、cat変数とobject2.categoryを共に、OBJECT1のkeyですよ、と明示してあげれば無事動きました!!

6. 最後に思ったこと

  • 自分のわかっている知識の範囲だと、型付けはバグを防げて便利だなと言う印象。
  • 自分のわからない範囲の知識が必要で、型に起因するエラーが出ると、型付けめんどくさ!ってなる。
  • 結論、もっと勉強しましょう。今回も良い勉強になりました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

React入門編

Reactの学習を開始しました。今後学習進捗や気付きを投稿します。ただの個人用備忘録のため悪しからず。
簡単な学習予定ロードマップは以下

ドットインストール React入門、ToDoリスト作成にて基本構文を学ぶ
Udemy 動画学習にて~中級レベルまでを学ぶ
Reactホームページによるチュートリアル
React-routerにてルーティング
Reduxにて状態管理
ReduxSaga、ReduxThunkにて非同期通信の制御
Next.jsによるサーバーサイドレンダリング

深い理解を得ることを目的に制作によるアウトプットを適時行う

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

【初心者向け】Reactで動くToDoアプリの作り方

ご挨拶

Ateam Lifestyle Advent Calendar 2020の8日目は、株式会社エイチームライフスタイル デザイナー @snd-07 が担当します!

この記事について

2020年を振り返ってみると、業務触れるReactを理解するため、フロントエンドの勉強が中心でした。
Progateやドットインストールなどで学習を進め、「なんとなく書いてあることはわかる」「こういう機能がある」という所まではステップアップできたと思います。

しかし現在、実践でコードを書くことができない所が課題になっているので、実際に簡単なアプリを作ることにしました。
また、Qiitaに投稿することで、自分の理解を言語化するチャレンジにしようと考えています。

できるだけ、自分がどう考え、どうしたかを記載し、私のようなフロントエンドの勉強を始めたばかりの人でもトライしやすいような記事にしていますので、ぜひみなさんも見ながらチャレンジしてみてください。
「Reactを勉強しはじめたばかり」「何か作ってみたいけど、何から始めたらいいか分からない」といった人におすすめです:sun_with_face:

作ったもの

機能

  • タスク一覧を表示する
  • タスクを追加できる
  • タスクを削除できる

挙動

todoアプリ挙動.gif

作成手順

1. UIを作る

  • まずはUIを作ります。
    • 最初からコンポーネントにしてしまったり、jsを書いてしまうと頭が混乱してしまいます:frowning2:
    • 仮の文字などで、ベタで書いて1つずつ進めていくことにします。
App.jsx
import React from "react";
import "./styles.css";

export default function App() {
  return (
    <div className="App">
      <h1 className="title">TODO</h1>
      <ul className="list">
        <li>
          タスク1
          <button className="delete">×削除</button>
        </li>
        <li>
          タスク2
          <button className="delete">×削除</button>
        </li>
      </ul>
      <div className="add">
        <input
          name="title"
          type="text"
          className="addInput"
          placeholder="タスクを追加する"
        />
        <button className="addButton">追加する</button>
      </div>
    </div>
  );
}
  • まだボタンを押しても何の処理も走りません。タスクのリストも、仮のテキストで作っておきます。
  • style.cssはここでは省略します。(こちらで見ることができます

2. タスクを配列で管理し、追加できるようにする

  • 「タスクを追加する」ボタンを押すと、<li></li>に追加されるようにします。

2.1 タスクを配列にして表示させる

App.jsx
const tasks = ["タスク1", "タスク2"];
App.jsx
<ul className="list">
  {tasks.map((task) => {
    return (
      <li key={task}>
        {task}
        <button className="delete">×削除</button>
      </li>
     );
  })}
</ul>

2.2 追加ボタンを押したら配列に追加されるようにする

App.jsx
const [tasks, setTasks] = useState(["タスク1", "タスク2"]); //const tasks = ["タスク1", "タスク2"]; は削除
const [text, setText] = useState("");
App.jsx
<div className="add">
  <input
    name="title"
    type="text"
    className="addInput"
    placeholder="タスクを追加する"
    value={text}
    onChange={(event) => {
      setText(event.target.value);
    }}
  />
  <button
    className="addButton"
    onClick={() => {
      setTasks((task) => task.concat(text));
      setText("");
    }}
  >
    追加する
  </button>
</div>

3. タスクを削除ボタンで削除できるようにする

  • 削除ボタンを押すと、配列からその要素を削除できるようにします。
App.jsx
const handleRemoveTask = (index) => {
    const newTasks = [...tasks];
    newTasks.splice(index, 1);
    setTasks(newTasks);
  };
App.jsx
<ul className="list">
  {tasks.map((task,index) => {
    return (
      <li key={task}>
        {task}
        <button
          className="delete"
          onClick={() => {
            handleRemoveTask(index);
          }}
        >
          ×削除
        </button>
      </li>
     );
  })}
</ul>

4. 完成!

App.jsx
import React, { useState } from "react";
import "./styles.css";

export default function App() {
  const [tasks, setTasks] = useState(["タスク1", "タスク2"]);
  const [text, setText] = useState("");
  const handleRemoveTask = (index) => {
    const newTasks = [...tasks];
    newTasks.splice(index, 1);
    setTasks(newTasks);
  };
  return (
    <div className="App">
      <h1 className="title">TODO</h1>
      <ul className="list">
        {tasks.map((task, index) => {
          return (
            <li key={index}>
              {task}
              <button
                className="delete"
                onClick={() => {
                  handleRemoveTask(index);
                }}
              >
                ×削除
              </button>
            </li>
          );
        })}
      </ul>
      <div className="add">
        <input
          name="title"
          type="text"
          className="addInput"
          placeholder="タスクを追加する"
          value={text}
          onChange={(event) => {
            setText(event.target.value);
          }}
        />
        <button
          className="addButton"
          onClick={() => {
            setTasks((task) => task.concat(text));
            setText("");
          }}
        >
          追加する
        </button>
      </div>
    </div>
  );
}

まとめ

いかがだったでしょうか?

実際に作ってみたいものを作ってみることで、ただ文法をインプットするより、ぐんと理解度・書く力が上がりました。
次は、もっと複雑なものにチャレンジしてみようと思います!
また、この記事を書く上で、自分の実装・思考を振り返って整理することができたので、Qiitaへのアウトプットも継続して行いたいです。
これからも引き続き学習を進めていきます:tulip:

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

Reactでのスクロール連動エフェクトなら「react-intersection-observer」が良き

この記事は、株式会社エイチームフィナジー の Advent Calendar 2020 6日目の記事になります。

6日目は、React環境でスクロール連動エフェクトを実装する際に便利な
react-intersection-observerについて、デザイナーの@masaki632dがご紹介します。

背景

現在、React(JSフレームワーク)とEmotion(CSSinJS)を導入した環境でタスクを進めており、
特定の高さまでスクロールしてきた時にテキストにマーカーが引かれるやつを実装する機会がありました。

当初は、JavaScriptのscrollイベントやwindow.pageYOffsetなどを使って一度実装したのですが、
この手法だとスクロールのたびに関数が呼び出されるため、パフォーマンスに影響を及ぼしてしまうようです。

scrollイベントの手法で実装後、ふとエンジニアから、
「最近はこれで実装するのがパフォーマンスも軽くて良きです」と紹介されたのが、
「Intersection Observer」 でした。(名前がカッコ良い)

なるほど!と思った数日後には、
エンジニア側で軽やかに「Intersection Observer」で実装完了されており、
表示を確認すると、特定の高さまでスクロールしてきた時にテキストにマーカーが引かれるやつがしっかり再現されていました。

今後同じような実装が必要になった時、自分の方でも軽やかに実装したいと思ったのと、
せっかくのReact環境ということで、
今回はreactと名前の付いたreact-intersection-observerで実装を試してみました。

Intersection Observer とは

「Intersection(要素間の交差)」を「Observe(監視)」するAPIのことです。
指定したDOM要素の交差点(DOM)を監視することができます。
「Intersection Observer」の詳細はこちら

ブラウザサポートも拡充しており、今後標準となる技術のようです。
「Intersection Observer」の対応ブラウザはこちら

react-intersection-observer とは

今回使用するライブラリ react-intersection-observer は、
上記の Intersection Observer API をReactで簡単に扱うためのライブラリになります。
「react-intersection-observer」の詳細はこちら

何はともあれ実装

  • $ yarn add でライブラリ react-intersection-observer をインストールします。 (package.jsonyarn.lockに react-intersection-observer が追加されます。)
$ yarn add react-intersection-observer
  • コンポーネントに使用していきます。
index.tsx
/** @jsx jsx */
import { FC } from "react";
import { jsx } from "@emotion/core";
import { styles } from "./Styled";

import { useInView } from 'react-intersection-observer';

export const index: FC = () => {
  // Hooksを使って簡単に書くことができます。
  // refで要素を指定して、inViewを使って要素がViewに入ったかどうかを判定します。
  // Optionについては、rootMarginを設定。要素が100pxより上に入った段階でinViewを取得できます。
  const [ref, inView] = useInView({
    rootMargin: '-100px 0px',
  });

  return (
    // スクロールして要素が表示されると同時に styles.show が付与される
    <p ref={ref} css={[styles.yellow, inView && styles.show]}>
      テキストテキスト
    </p>
  );
};

  • Styled.ts
import { css } from "@emotion/core";

export const styles = {
  // マーカー箇所のstyle
  yellow: css`
    width: 200px;
    margin: 0 auto;
    text-align: center;
    opacity: 0;
    transition: 2s;
    background: -webkit-linear-gradient(
      left,
      rgb(255, 250, 153) 50%,
      transparent 50%
    );
    background-repeat: no-repeat;
    background-size: 200% 0.8em;
    background-position: 100% 0.5em;
  `,

  // スクロールして要素が表示されると同時に付与されるstyle
  show: css`
    opacity: 1;
    background-position: 0% 0.5em;
    animation: SlideIn 3s ease-out both;
    transform: translateY(-10px);
  `,
};
  • ブラウザをスクロールして確認すると、
    テキスト箇所が表示される高さになった瞬間に、アニメーションが発火してくれました!
    (動き的には、ふわっと下から表示 + マーカーが左から引かれる) 画面収録_黄色マーカー.gif

利用に便利なシチュエーション

  • 特定の高さまでスクロールしてきた時にテキストにマーカーが引かれるやつ
  • 画像の遅延ロード
  • YouTubeの自動再生
  • コンテンツの追加読み込み
    などなど

まとめ

いかがだったでしょうか?
今回はReact環境で簡単にIntersection Observer APIを使用することができる、
react-intersection-observerをご紹介しました。
とても簡単で便利ですので、ぜひ一度使ってみてください。

参考

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

そろそろNode14へ移行せな

はじめに

  • 2020/4/22にNode.js14がリリースされました。
  • また、2020/10/27にNode.js14のActive LTSが開始され、2020/11/30にNode.js12のMaintenance LTSに移った為、そろそろ切り替え時かなということで、この記事を残します。

参考: Node公式リリース時期
スクリーンショット 2020-11-30 13.03.47.png

LTSってなんだ??

LTSとは、[Long Term Support]の略を指し、長期の保守運用が約束されているバージョンになります。

Current LTS

  • 最新版だが、安定性を約束しないことで機能追加を盛り込んだバージョン

Active LTS

  • リリースラインに適切で安定していると判断された新機能、バグ修正、および更新。

安定しているため、本番環境をアップグレードする最適な時期ともいえます

Maintenance LTS

  • 重大なバグ修正とセキュリティアップデート

Node14の新機能

診断レポートの安定

  • 診断レポートは、Node14の安定した機能としてリリースされています (Node12では、実験的な機能として追加されていました)

→ 診断レポート機能を使用すると、オンデマンドまたは特定のイベントが発生したときにレポートを生成できます。

  • このレポートには、クラッシュ、パフォーマンスの低下、メモリリーク、高いCPU使用率、予期しないエラーなど、本番環境での問題の診断に役立つ情報が含まれています。

実行方法については、次のように[--report-on-fatalerror]を指定します。
また、例外がcatchされなかったときにレポートを出力する[--report-uncaught-exception]などがあります。

node --report-on-fatalerror server.js

参照: 診断レポート機能の詳細

V8がV8 8.1にアップグレード

V8のバージョンが上がることで使用できるJavaScriptの構文や機能が増えます。

Optional Chaining

Optional chainingは、参照したオブジェクトや関数の値がundefinedやnullの可能性があっても、その値が持つプロパティに安全にアクセスすることができます。

example.js
// 使用前
let nameLength;
if (user && user.info && user.info.name)
  userName = user.info.name;

// Optional Chainingを使用
const userName = user?.info?.name;

参照: MDN_Optional Chaining

Nullish Coalescing

Nullish coalescingは、参照する値がundefined または null の時、デフォルト値を取得することができます。

example.js
const resultString = null ?? 'default';
console.log(resultString);
// => default

const resultNumber = 0 ?? 42;
console.log(resultNumber);
// => 0

参照: MDN_Nullish Coalescing

Intl.DisplayNames

Intl.DisplayNamesは、指定したロケールとオプションに基づいた表示名称の翻訳を取得することができます。

example.js
// 国/地域コードから国名/言語名を出力する例
const languageNamesInEnglish = new Intl.DisplayNames(['en'], { type: 'language' });
const languageNamesInFrance = new Intl.DisplayNames(['fr'], { type: 'language' });

console.log(languageNamesInEnglish.of('ja'));
// => "Japanese"
console.log(languageNamesInFrance.of('en-US'));
// => "anglais américain"

参照: MDN_Intl.DisplayNames

Intl.DateTimeFormatのcalendar optionとnumberingSystemオプションの有効化

Intl.DateTimeFormatのoptions引数を用いて、calendarとnumberingSystemが使えるようになりました。

example.js
const date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));

console.log(new Intl.DateTimeFormat('en-US').format(date));
// => "12/20/2012"

console.log(new Intl.DateTimeFormat('en-GB').format(date));
// => "20/12/2012"

console.log(new Intl.DateTimeFormat('ja', { calendar: 'japanese',  numberingSystem: 'jpan', era: 'long' }).format(date));
// => "平成24年十二月二十日"

参照: MDN_Intl.DateTimeFormat

実験的にAsync Local Storage APIの追加

AsyncLocalStorageは、コールバックとプロミスチェーン内に非同期状態を作成するために使用されます。

→ これにより、Webリクエストの存続期間またはその他の非同期期間を通じてデータを保存できます。これは、他の言語のスレッドローカルストレージに似ています。

参照: ドキュメント_AsyncLocalStorage

Streams API全体の一貫性を向上

変更点としては、

  • [http.OutgoingMessage] → [stream.Writable]に一貫しました。

  • [net.Socket] → [stream.Duplex]に一貫しました。

変更としては以上ですが、アプリケーションに影響はないと思っています。

ES Moduleの警告を削除

ES Modulesとは

JavaScriptにおけるモジュール機能としては、下記のものがあります。

  • CommonJS
  • ECMAScript Modules(ES Modules)
  • etc..

CommonJS

CommonJSとは、言語仕様のModules解決するために主にNodeに実装されています。

example.js
const { test } = require("./test");

ES Modules

ES Modulesとは、再利用のためにJavaScriptコードをパッケージ化するための公式の標準形式です。

example.js
import { test } from "./test.js"

じゃあどうなったの??

今までは、ES Modulesを使用する場合、以下の警告が表示されていました。

ExperimentalWarning: The ESM module loader is experimental.

これが、Node.js v14 からは上記の警告は表示されなくなります。
注意点としては、あくまでまだ実験的なものであることです

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

そろそろNode.js 14へ移行せな (新機能まとめ)

はじめに

  • 2020/4/22にNode.js14がリリースされました。
  • また、2020/10/27にNode.js14のActive LTSが開始され、2020/11/30にNode.js12のMaintenance LTSに移った為、そろそろ切り替え時かなということで、この記事を残します。

参考: Node公式リリース時期
スクリーンショット 2020-11-30 13.03.47.png

LTSってなんだ??

LTSとは、[Long Term Support]の略を指し、長期の保守運用が約束されているバージョンになります。

Current LTS

  • 最新版だが、安定性を約束しないことで機能追加を盛り込んだバージョン

Active LTS

  • リリースラインに適切で安定していると判断された新機能、バグ修正、および更新。

安定しているため、本番環境をアップグレードする最適な時期ともいえます

Maintenance LTS

  • 重大なバグ修正とセキュリティアップデート

Node14の新機能

診断レポートの安定

  • 診断レポートは、Node14の安定した機能としてリリースされています (Node12では、実験的な機能として追加されていました)

→ 診断レポート機能を使用すると、オンデマンドまたは特定のイベントが発生したときにレポートを生成できます。

  • このレポートには、クラッシュ、パフォーマンスの低下、メモリリーク、高いCPU使用率、予期しないエラーなど、本番環境での問題の診断に役立つ情報が含まれています。

実行方法については、次のように[--report-on-fatalerror]を指定します。
また、例外がcatchされなかったときにレポートを出力する[--report-uncaught-exception]などがあります。

node --report-on-fatalerror server.js

参照: 診断レポート機能の詳細

V8がV8 8.1にアップグレード

V8のバージョンが上がることで使用できるJavaScriptの構文や機能が増えます。

Optional Chaining

Optional chainingは、参照したオブジェクトや関数の値がundefinedやnullの可能性があっても、その値が持つプロパティに安全にアクセスすることができます。

example.js
// 使用前
let nameLength;
if (user && user.info && user.info.name)
  userName = user.info.name;

// Optional Chainingを使用
const userName = user?.info?.name;

参照: MDN_Optional Chaining

Nullish Coalescing

Nullish coalescingは、参照する値がundefined または null の時、デフォルト値を取得することができます。

example.js
const resultString = null ?? 'default';
console.log(resultString);
// => default

const resultNumber = 0 ?? 42;
console.log(resultNumber);
// => 0

参照: MDN_Nullish Coalescing

Intl.DisplayNames

Intl.DisplayNamesは、指定したロケールとオプションに基づいた表示名称の翻訳を取得することができます。

example.js
// 国/地域コードから国名/言語名を出力する例
const languageNamesInEnglish = new Intl.DisplayNames(['en'], { type: 'language' });
const languageNamesInFrance = new Intl.DisplayNames(['fr'], { type: 'language' });

console.log(languageNamesInEnglish.of('ja'));
// => "Japanese"
console.log(languageNamesInFrance.of('en-US'));
// => "anglais américain"

参照: MDN_Intl.DisplayNames

Intl.DateTimeFormatのcalendar optionとnumberingSystemオプションの有効化

Intl.DateTimeFormatのoptions引数を用いて、calendarとnumberingSystemが使えるようになりました。

example.js
const date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));

console.log(new Intl.DateTimeFormat('en-US').format(date));
// => "12/20/2012"

console.log(new Intl.DateTimeFormat('en-GB').format(date));
// => "20/12/2012"

console.log(new Intl.DateTimeFormat('ja', { calendar: 'japanese',  numberingSystem: 'jpan', era: 'long' }).format(date));
// => "平成24年十二月二十日"

参照: MDN_Intl.DateTimeFormat

実験的にAsync Local Storage APIの追加

AsyncLocalStorageは、コールバックとプロミスチェーン内に非同期状態を作成するために使用されます。

→ これにより、Webリクエストの存続期間またはその他の非同期期間を通じてデータを保存できます。これは、他の言語のスレッドローカルストレージに似ています。

参照: ドキュメント_AsyncLocalStorage

Streams API全体の一貫性を向上

変更点としては、

  • [http.OutgoingMessage] → [stream.Writable]に一貫しました。

  • [net.Socket] → [stream.Duplex]に一貫しました。

変更としては以上ですが、アプリケーションに影響はないと思っています。

ES Moduleの警告を削除

ES Modulesとは

JavaScriptにおけるモジュール機能としては、下記のものがあります。

  • CommonJS
  • ECMAScript Modules(ES Modules)
  • etc..

CommonJS

CommonJSとは、言語仕様のModules解決するために主にNodeに実装されています。

example.js
const { test } = require("./test");

ES Modules

ES Modulesとは、再利用のためにJavaScriptコードをパッケージ化するための公式の標準形式です。

example.js
import { test } from "./test.js"
じゃあどうなったの??

今までは、ES Modulesを使用する場合、以下の警告が表示されていました。

ExperimentalWarning: The ESM module loader is experimental.

これが、Node.js v14 からは上記の警告は表示されなくなります。
注意点としては、あくまでまだ実験的なものであることです

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

Reactで排他的なチェックボックスを実装する

はじめに

訳あって、Reactで排他的なチェックボックスを実装する必要がありました。
ここでいう「排他的」は、グループにつき一個しかチェックできないこと(単一選択)を指しています。
別題(というかタイトル候補)は、「Reactでラジオボタンのようなチェックボックスを実装する」です。

コピペできる全コード付き + 解説ありなので、
初心者でも分かりやすい内容になっていると思います。

作成したチェックボックス

というわけで、2種類のチェックボックスを作成しました。
一つ目は必ず一つを選択しなければならない、チェックが外せないチェックボックスです。
二つ目はチェックが外せます。チェックの数は0か1ですね。
useStateでチェックの値を管理しています。

片方だけを読んでも分かるように、同じような構成で書いていまして、
重複もしくは全く一緒な内容は結構あります。
2種類とも読んでくださる方には申し訳ないですが、ご了承ください。

チェックを外せないパータン

完成イメージ

初期状態

image.png

選択後

image.png

全体コード

import React, { useState } from "react";

const MyForm = () => {
  const initializedData = {
    themeColor: "default"
  };

  const [data, setData] = useState(initializedData);

  const handleThemeColorChange = (e) => {
    const newData = { ...data, themeColor: e.target.value };
    setData(newData);
  };

  return (
    <form>
      テーマ:
      <input
        type="checkbox"
        id="themeDeafault"
        value="default"
        checked={data.themeColor === "default"}
        onChange={handleThemeColorChange}
      />
      <label htmlFor="themeDeafault">デフォルト </label>
      <input
        type="checkbox"
        id="themeRibbon"
        value="ribbon"
        checked={data.themeColor === "ribbon"}
        onChange={handleThemeColorChange}
      />
      <label htmlFor="themeRibbon">リボン </label>
      <input
        type="checkbox"
        id="themeDog"
        value="dog"
        checked={data.themeColor === "dog"}
        onChange={handleThemeColorChange}
      />
      <label htmlFor="themeDog">犬 </label>
      <input
        type="checkbox"
        id="themeNature"
        value="nature"
        checked={data.themeColor === "nature"}
        onChange={handleThemeColorChange}
      />
      <label htmlFor="themeNature">自然 </label>
    </form>
  );
};

解説

値の状態管理

  // データの初期値を定義
  const initializedData = {
    themeColor: "default"
  };

  // hooksで状態管理する
  const [data, setData] = useState(initializedData);

チェックボックスだけではなく、フォーム内に複数のデータがあるイメージだったので、
まずはフォーム全体をinitializedDataとします。
そして、今回のチェックボックスの値として、中にthemeColorを追加します。
必ずどれか選択しているとのことなので、
初期状態として、default(画面上の「デフォルト」)を選択させます。

準備が終わったら、hooksのuseStateを使って、
dataとsetDataを定義します。

HTML

  <input
    type="checkbox"
    id="themeRibbon"
    value="ribbon"
    checked={data.themeColor === "ribbon"}
    onChange={handleThemeColorChange}
  />
  <label htmlFor="themeRibbon">リボン </label>

4つのチェックボックスがありますが、
作りがまったく一緒なので、2番目の「リボン」で説明します。

上から順に説明しますので、まずは<input>からですね。
typeは入力欄の種別を定義できます。type="checkbox"でチェックボックスを作ります。
idはHTML部品の識別子になります。ページの中に、idを重複させない(一意的である)のが基本です。
valueにはチェックボックスが表している値を入れます。(詳細後述)
checkedがtrueの場合、チェックされる状態になります。falseの場合、チェックが外している状態になります。
今回は右側を{data.themeColor === "ribbon"}にすることによって、
動的にdata.themeColorの値によってチェックボックスの状態を変化させることができます。
"ribbon"だったら、チェックされる。"ribbon"以外の値だったら、チェックされない。)
onChangehandleThemeColorChangeという関数を入れました。(内容後述)
入力が変更される際に上記の関数を実行するようになります。
チェックボックスの場合、クリック = 値の変化(チェックする/チェックを外す)というところがあるため、
クリックされる度にonChangeは発火します。

次には<label>です。
htmlFor<input>idと同じ値を入れることによって、ラベルとチェックボックスを関連付けることができます。
この状態でラベルの「リボン」をクリックすると、チェックボックスがクリックされた時と同様の動きになります。

ちなみに、htmlForはReactの書き方になります。
通常のHTML(Reactビルド後)だと、以下のようになります。

<label for="themeRibbon">リボン </label>

こうなっている理由について、上記のリンクから引用します。

for は JavaScript での予約語であるため、React 要素では代わりに htmlFor を使用します。

onChangeイベント

先ほど、<input>onChangehandleThemeColorChangeという関数を入れました。
こちらの関数です。

  const handleThemeColorChange = (e) => {
    const newData = { ...data, themeColor: e.target.value };
    setData(newData);
  };

関数全体はアロー関数で書いており、functionを使った書き方はこうです。

  // 関数式の書き方
  function handleThemeColorChange(e) {
    const newData = { ...data, themeColor: e.target.value };
    setData(newData);
  };

また、TypeScriptの方のために、eの型も記載しておきます。

e: React.ChangeEvent<HTMLInputElement>

ここからは関数の中身を説明します。

一行目

    // ストアのデータを更新するために、新しい値を使って新しいデータを作成
    const newData = { ...data, themeColor: e.target.value };

...data:スプレッド構文で既存のデータを展開する。
, themeColor::newData.themeColorの値を定義する際の左側。
e.target.value<input>valueにいれた値を取得。

 // リボンのチェックボックス(value="ribbon")がクリックされた際
 console.log(e.target.value === "ribbon");  // true

二行目

    // ストア更新
    setData(newData);

setDataにnewDataを渡すことによって、ストアのdataを書き換えることができます。

チェックを外せるパータン

完成イメージ

初期状態

image.png

選択後

image.png

全体コード

import React, { useState } from "react";

const MyForm = () => {
  const initializedData = {
    notifyFrequency: "",
  };

  const [data, setData] = useState(initializedData);

  const handleFrequencyChange = (e) => {
    const newValue = (e.target.value === data.notifyFrequency) ? "" : e.target.value;
    const newData = { ...data, notifyFrequency: newValue };
    setData(newData);
  };

  return (
    <form>
      通知頻度:
      <input
        type="checkbox"
        id="notifyAlways"
        value="always"
        checked={data.notifyFrequency === "always"}
        onChange={handleFrequencyChange}
      />
      <label htmlFor="notifyAlways">常時 </label>

      <input
        type="checkbox"
        id="notifyDaily"
        value="daily"
        checked={data.notifyFrequency === "daily"}
        onChange={handleFrequencyChange}
      />
      <label htmlFor="notifyDaily">毎日 </label>

      <input
        type="checkbox"
        id="notifyWeekly"
        value="weekly"
        checked={data.notifyFrequency === "weekly"}
        onChange={handleFrequencyChange}
      />
      <label htmlFor="notifyWeekly">毎週 </label>

      <input
        type="checkbox"
        id="notifyMonthly"
        value="monthly"
        checked={data.notifyFrequency === "monthly"}
        onChange={handleFrequencyChange}
      />
      <label htmlFor="notifyMonthly">毎月 </label>
    </form>
  );
};

解説

値の状態管理

  // データの初期値を定義
  const initializedData = {
    notifyFrequency: ""
  };

  // hooksで状態管理する
  const [data, setData] = useState(initializedData);

チェックボックスだけではなく、フォーム内に複数のデータがあるイメージだったので、
まずはフォーム全体をinitializedDataとします。
そして、今回のチェックボックスの値として、中にnotifyFrequencyを追加します。
初期状態として、何も選択されていないことを表す""(空文字列)にしました。

準備が終わったら、hooksのuseStateを使って、
dataとsetDataを定義します。

HTML

  <input
    type="checkbox"
    id="notifyDaily"
    value="daily"
    checked={data.notifyFrequency === "daily"}
    onChange={handleFrequencyChange}
  />
  <label htmlFor="notifyDaily">毎日 </label>

4つのチェックボックスがありますが、
作りがまったく一緒なので、2番目の「毎日」で説明します。

上から順に説明しますので、まずは<input>からですね。
typeは入力欄の種別を定義できます。type="checkbox"でチェックボックスを作ります。
idはHTML部品の識別子になります。ページの中に、idを重複させない(一意的である)のが基本です。
valueにはチェックボックスが表している値を入れます。(詳細後述)
checkedがtrueの場合、チェックされる状態になります。falseの場合、チェックが外している状態になります。
今回は右側を{data.notifyFrequency === "daily"}にすることによって、
動的にdata.notifyFrequencyの値によってチェックボックスの状態を変化させることができます。
"daily"だったら、チェックされる。"daily"以外の値だったら、チェックされない。)
onChangehandleFrequencyChangeという関数を入れました。(内容後述)
入力が変更される際に上記の関数を実行するようになります。
チェックボックスの場合、クリック = 値の変化(チェックする/チェックを外す)というところがあるため、
クリックされる度にonChangeは発火します。

次には<label>です。
htmlFor<input>idと同じ値を入れることによって、ラベルとチェックボックスを関連付けることができます。
この状態でラベルの「毎日」をクリックすると、チェックボックスがクリックされた時と同様の動きになります。

ちなみに、htmlForはReactの書き方になります。
通常のHTML(Reactビルド後)だと、以下のようになります。

<label for="notifyDaily">毎日 </label>

こうなっている理由について、上記のリンクから引用します。

for は JavaScript での予約語であるため、React 要素では代わりに htmlFor を使用します。

onChangeイベント

先ほど、<input>onChangehandleFrequencyChangeという関数を入れました。
こちらの関数です。

  const handleFrequencyChange = (e) => {
    const newValue = (e.target.value === data.notifyFrequency) ? "" : e.target.value;
    const newData = { ...data, notifyFrequency: newValue };
    setData(newData);
  };

関数全体はアロー関数で書いており、functionを使った書き方はこうです。

  // 関数式の書き方
  function handleFrequencyChange(e) {
    const newValue = (e.target.value === data.notifyFrequency) ? "" : e.target.value;
    const newData = { ...data, notifyFrequency: newValue };
    setData(newData);
  };

また、TypeScriptの方のために、eの型も記載しておきます。

e: React.ChangeEvent<HTMLInputElement>

ここからは関数の中身を説明します。

一行目

    // notifyFrequencyに入れるための新しい値を取得
    const newValue = (e.target.value === data.notifyFrequency) ? "" : e.target.value;

e.target.value<input>valueにいれた値を取得。
data.notifyFrequency:既存のnotifyFrequencyを取得。

 // 毎日のチェックボックス(value="daily")がクリックされた際
 console.log(e.target.value === "daily");  // true

外せるチェックボックスの場合、チェック済みだったら外す、そうでなければチェックするというロジックになります。
そのため、まずは「チェック済みか」を知る必要があります。

 (e.target.value === data.notifyFrequency)

この条件式はまさにそのためです。
両者を比較して、同じ場合(=チェック済み)はtrue、違う場合(=チェックされていない)はfalseになります。
後は三項演算子を使い、
newValue""もしくはe.target.valueを代入して宣言します。

二行目

    // ストアのデータを更新するために、新しい値を使って新しいデータを作成
    const newData = { ...data, notifyFrequency: newValue };

...data:スプレッド構文で既存のデータを展開する。
, notifyFrequency::newData.notifyFrequencyの値を定義する際の左側。
newValue:新しい値。

三行目

    // ストア更新
    setData(newData);

setDataにnewDataを渡すことによって、ストアのdataを書き換えることができます。

さいごに

簡単な内容ではありますが、ついつい説明を足したくなります(汗)
長くなってしまいました。
ご質問やご指摘はいつでも受け付けますので、
コメントや編集リクエストをよろしくお願いします。

横並びしている4つのチェックボックスの作りがまったく一緒なので、
工夫すればとループで作成することもできます。
興味のある方はぜひ挑戦してみてください。

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

知識の無い新卒がNext.jsとASP.NET CoreでTodoアプリを作成しコンテナ化したお話

こんにちは、新卒のますだです。※あだ名は絶賛募集中です:cry:
本記事は弥生 Advent Calendar 2020の12日目の記事になります。
12/12とバランスが良かったのでこの日を選びました。

一か月ちょっとでTodoアプリを作成しました。
「どういった流れで新しい技術を学び、成果物を作成したのか」
について当時のますだの心情と共に、簡潔に書いていきたいと思います。
温かい目で見て頂けると幸いです。

簡単な自己紹介

  • 2020年に弥生に新卒として入社

  • 基本的なjavaの知識はある

  • 楽観的でポジティブ

mgramでは「異常に怖いもの知らず」という診断結果がでました。
また、mgramは入社直後と入社半年後で二回診断したのですが、
運命の人と出会う確率が1/3188から1/10235に下がったので、結婚願望が強い人は仕事をしない方が良いと思いました。

上司からの依頼(トレーニング内容)

  1. Next.jsだけを使ってTodoアプリを作成せよ!(Visual Studio Codeで作成)

  2. ASP.NET Coreでバックエンドサービスを作成せよ!!(Visual Studioで作成)

  3. 1と2で作成した成果物を繋げよ!!!

  4. 3で作成した成果物をDockerでコンテナ化せよ!!!!(Visual Studio Codeで作成)

要件:
 ・タスク一覧が見られること
 ・タスクが追加・編集・削除できること
 ・タスクは以下の項目を持つこと。タスク名・詳細・期日・完了フラグ
 ・作成した成果物はgitLabにあげよ。

ますだの心情

  • gitってどう使うんだっけ...

  • Next.js...?

  • ASP.NET Core...??

  • 繋げる...???

  • Docker...????

「??????????????????????」と脳内は?だらけでした。

Next.jsとASP.NET Coreとdockerを簡単に説明

  • Next.js

    • ZEIT社によって開発されたJavascriptのフレームワーク
    • ReactのSSR・SSGを実現。簡単にいうと、ブラウザ上ではなくサーバー側でデータをレンダリングし、HTMLファイルを表示する。
    • メリット
      • サーバー側でレンダリングするためコンテンツの表示が早い
      • SEOの向上
      • ルーティングが楽 など
  • ASP.NET Core

    • マイクロソフト社が提供しているWebアプリケーション開発フレームワーク
    • マルチプラットフォーム(Windows,Linux,Mac)で動作する.NET環境
    • メリット
      • OSに依存せず開発できる
      • WEBブラウザで表示できるためデバッグが楽 など
  • docker

    • Docker社によって開発されたコンテナ型の仮想環境を作成、配布、実行できるプラットフォーム
    • ユーザーが作成した環境やソースコードなどをパッケージ化(コンテナ化)することができる。  コンテナ化したものは他のパソコンで実行することが可能
    • メリット:
      • ユーザーが開発したアプリケーションを環境構築せずに実行できる
      • メモリやディスクの消費量を少なく抑えた状態で仮想化するため、立ち上げるスピードが速い

作成した成果物

  • 実際のアプリケーション
    ※今回はトレーニングでTodoアプリを作成したためcssは無視しています。
    training.gif

  • 以下の画像はTodoアプリの繋がりを示しています。

    • トレーニング1.Next.jsだけでTodoアプリを作成の全体図: Next.js.jpg
    • トレーニング2.3. 4. Next.jsとASP.NET CoreでTodoアプリを作成の全体図: ASP.NET CoreとNext.js.jpg
  • 成果物を作成した基本的な手順は

  1. 公式チュートリアルをプレイ
  2. パワーポイントで実装のイメージを書きだし検証
  3. 検証した内容を上司に見せる
  4. 実装
  5. レビュー です。 ※手順や検証は我流です

トレーニング1. Next.jsだけを使ってTodoアプリを作成せよ!

  • まずはNext.jsの公式チュートリアル(英語が読めないため日本語訳サイト)をプレイ
    ますだ「なるほど、こういう動きをするのか。」(体感進捗率:10%)
  • 次は実装する前にtodoアプリの検証
    ますだ「一文字も書けん:scream:」(体感進捗率:5%)
  • 一文字も書けなかったため、Next.jsでtodoアプリを作成しているサイトのコードを理解
    ますだ「todoアプリを作成できそうだ:smile:」(体感進捗率:10%)
  • 再度todoアプリの検証
    ますだ「DB的な役割を持つファイル(todoList.js)はどうやって作成すればいいんだ...:cold_sweat:」(体感進捗率:5%)
  • 上司の方に相談
    Uさん「API Routesを使用し、サーバー側でtodoの値を保持しよう!API Routesを使えばトレーニング3. にも活かせるはず」
    ますだ「API Routesを使うのか。よし勉強だ!!:muscle:」(体感進捗率:10%)
  • API Routesの基本的な動きが分かったため再度todoアプリの検証 ※[1]ここでのの検証内容
    ますだ「いけそうかも:yum:」(体感進捗率:50%)
  • todoアプリを実装
    ますだ「うごいたぞ!:sunglasses:」(体感進捗率:80%)
  • ここで上司の方にレビュー依頼
    Uさん「CRUDのDELETEにbodyはNG。queryを使用しよう!」
    ますだ「:fearful:」(体感進捗率:20%)
  • DELETEにbodyではなくqueryを持たせるためにダイナミックルーティングを使用して再度実装※[2]ここでのの検証内容
    ますだ「できだ:japanese_goblin:」(体感進捗率:100%)

※[1]ここでの検証内容
[1].jpg

※[2]ここでのの検証内容
[2].jpg

トレーニング2. ASP.NET Coreでバックエンドサービスを作成せよ!!

  • まずは公式のチュートリアル(日本語版の公式チュートリアルはコードが載っていない部分が多いため英語版を推奨)
    ますだ「チュートリアルの内容がtodoアプリの作成だと...ありがてぇ:joy:
    ますだ「Visual Studioが自動で色々と作成してくれる...賢けぇ:innocent:」(体感進捗率:30%)
  • 大体の流れは掴めたため検証に入る
    ますだ「公式チュートリアルの内容を少し変えるだけで動きそうだ:smirk:」(体感進捗率:50%)
  • いざ実装。動作の確認はPostmanを使用
    ますだ「動いた...Postmanすごく便利:two_hearts:
    ますだ「Visual Studioが勝手にコードを書いてくれたから達成感が無い:innocent:」(体感進捗率:100%)

トレーニング3. 1と2で作成した成果物を繋げよ!!!

  • まずは公式のチュートリアルをプレイ
    ますだ「Visual Studioを使用し、Javascript(front)とASP.NET Core(backend)を繋げる方法は分かった:neutral_face:
    ますだ「が、Next.js(front)はVScodeを使用している...どうすればいいんだ:tired_face:」(体感進捗率:10%)
  • ますだの力ではGoogle先生だけで解決することができなかったため、Uさんに相談
    Uさん「Next.jsはVScode、ASP.NET CoreはVisual Studioで動かせます。」
    ますだ「そんなことできるのか...:flushed:」(体感進捗率:30%)
  • Visual Studioでbackend(ASP.NET Core)を起動し、起動したURIにリクエストを投げれば動いた
todo.js
//todoを追加する処理
const uri = "<Visual Studioで起動したuri>";
case "POST":
      await fetch(uri, {
        method: "POST",
        headers: {
          Accept: "application/json",
          "Content-Type": "application/json",
        },
        body: todoJson,//追加したいtodo
      }).catch((error) => console.error("Unable to add item.", error));
      res.status(200).json(todoJson);
  • 無事Next.jsとASP.NET Coreを繋げることができたが、期日が未入力の時だけうまく動かない
    ますだ「エラーもでねぇ...デバッグしまくるしかねぇ...:astonished:」(体感進捗率:30%)
  • デバッグした結果、C#(ASP.NET Core)が期待通りに動いていないことが分かった。原因はC#のdate型
    ますだ「どうやらC#は特殊な宣言(Null許容型)をしないとdate型にnullが入らないらしい:weary:」(体感進捗率:80%)
TodoItem.cs
//型の後ろに?を付けるとNull許容型になるらしい
public DateTime? Date { get; set; }
  • 数多の困難を乗り越え無事に実装完了
    ますだ「:sob:」(体感進捗率:100%)

トレーニング4. 3で作成した成果物をDockerでコンテナ化せよ!!!!

  • いよいよ最後のトレーニング。まずは恒例の公式チュートリアル(日本語翻訳)を読む
    ますだ「いや、まったく分からん:innocent:」(体感進捗率:0%)
  • とりあえずマイクロソフトのドキュメントを参考にコンテナ化を試みる
    ますだ「Visual Studioが賢すぎて勝手にコンテナ化できてしまった...:innocent:」(体感進捗率:3%)
  • 仮想化の概念も分からないため噛み砕いて説明してる動画をyoutubeで視聴
    ますだ「これが...無料!?:anguished:」(体感進捗率:20%)
  • Dockerを抽象的に理解したため検証に入る
    ますだ「...:innocent:」(体感進捗率:2%)
  • ここで相談役のKさんに自分の理解を伝えた。Kさんと話す中でDockerの理解がどんどんと深まった
    ますだ「お忙しい中何度も助けて頂き、感謝感激雨霰です:zap:」(体感進捗率:50%)
  • 今度こそDockerをそこそこ理解できたため検証し、実装に入る
    ますだ「書ける、書けるぞ!!:laughing:」(体感進捗率:80%)
  • VScodeでNext.jsとASP.NET Coreをコンテナ化(docker-compose)しようと試みたが期待通りに動かない。 どうやらASP.NET Core側でエラーが起きている。
    ますだ「Visual Studioに自動で作成して頂いた箇所がうまく動かない...Visual Studioに頼りすぎは良くない:persevere:
    (体感進捗率:50%)
  • Kさんのお力添えもあり、なんとかエラーの原因を突き止めた。どうやらbuildするときの階層が違ったらしい。
    ますだ「Visual StudioでDockerを実行すると自動で階層を指定してくれるらしい...:disappointed_relieved:」(体感進捗率:70%)
docker-compose.yml
//VScodeではDockerfileがある階層をしっかりと指定してあげる
build:
      context: backend/SampleApi
  • うまくビルドできた!!が、todoアプリがうまく動かない。色々と調査し、 backend(ASP.NET Core)のコンテナとfront(Next.js)のコンテナを繋ぐネットワークの作成が必要と考えた
    ますだ「世の中うまく進まねぇ...:sweat_smile:」(体感進捗率:50%)
  • 自分で実装する前に、Kさんに自分の理解を伝えた
    ますだ「ネットワークを作成する必要がありますよね??:sweat:
    Kさん「host.Docker.internalを使えばそんなことしなくてもいけるはず」
    ますだ「:flushed:」(体感進捗率:80%)
  • host.Docker.internalを使用し、いざ実行!
    ますだ「う、うごいた:sob:」(体感進捗率:100%)

さいごに

ここまで読んで頂きありがとうございました。
これがますだの一か月ちょっとの奮闘記でした。
ITリテラシーが低く苦労した点はたくさんありましたが、
周りの方に支えられ、なんとか動くものを作り上げることができました。
お忙しい中、質問に答えて頂きありがとうございました。特にUさんとKさんにはとてもお世話になりました!
今後はこの経験を活かし、新しい技術をどんどん取得していきたいと考えています!

明日の記事はnaoya_kimuraさんの「Visual Studioのパフォーマンスプロファイラーを使ってみた」です。私のフレッシュな記事とは違い、とても綺麗でわかり易い文章になってました!
お楽しみに!

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

フロントエンドのおすすめMac無料ツール2020下半期まとめ

フロントエンドだけではないかもしれないけど、
エンジニアがおすすめするMac無料ツール2020下半期まとめです。
関係ないけど10人くらいサンタが家に来てくれないかな....:santa_tone1::santa_tone2::santa_tone3::santa_tone4::santa_tone5:

目次

1.Mac Apps
2.Chrome Extension
3.まとめ

■ Mac Apps

:point_right_tone4: VSCode

だいたいのエンジニアがみんな使ってるよね。って思うけど一応記載しときまっす。エディタなんて好みだと思うけどね。
こやつは拡張性高いし必須だと思ってます。
好きなテーマはDraculaです。:smiling_imp:

:point_right_tone4: Draw.io Integration

VSCode拡張。Drow.io単体でも使うけど
Draw.ioをVSCode内で利用できる。エディタ内でグリグリ製図するの楽しいね。

:point_right_tone4: Postman

API開発・テスト便利ツール。
まぁこれは前からよく使われてるやつ。でも正直うまく使えてる自信はない。

:point_right_tone4: insomnia

API開発・テスト便利ツール。
REST APIやGraphQL APIのデータをチェックできる。
環境ごとに異なるパラメータを"environment"として定義することで、それをワンクリックで切り替えることができます。
また、色々な言語の仕様にそった対象のHTTPリクエストを実現するためのコードを生成して表示してくれます。詳しくはこちら

:point_right_tone4: Table Plus

SQLクライアント。
Sequel Pro(パンケーキ:honey_pot:)からの乗り換えとして最近使ってます。なんかこっちが主流になりつつあるぽい。
PostgreSQL,MySQL,MariaDB,SQLite,Amazon Redshift,Oracle,MongoDB等の主要どころはだいたいサポートしているそうです。
More coming soon てこっそり書いてあるので今後もアップデートどんどんされそう。

:point_right_tone4: clipy

コピペの履歴を保持。
⌘ + shift + vでさくっと呼び出す事ができる。 :bookmark_tabs:

:point_right_tone4: Just Focus

ポモドーロタイマーアプリ。:hourglass_flowing_sand:
時間になったらディスプレイをにゅるん!!ってUnsplashのおしゃれなランダム画像でふさいでBreakモードへ突入させます。
ポモドーロの一般的な作業時間は25分だけど、タイマー時間をpreferenceから変更できる。画像も変えれるみたいなのでお好みの画像を設定して至福のBreakTimeを...:coffee:
ポモドーロ最近はやってるよね。流行を追いかけてみた。
カップラタイマーとして使ってはいけない。:ramen: おしゃれ画像が台無しだ。

:point_right_tone4: kap

mac上の画面を録画するソフト。:video_camera:
様々な形式にexportできたり、トリミングできたりと便利なツール。Vercelとも連携できるそうな。連携してどうするのかは知らぬ。とりあえず最近はVercel!!Vercel!!言っとけばいい風潮ある。:mask:
ところでVercelの発音てヴァーセル?ヴァーサル?わたしはヴァーセル派。

:point_right_tone4: ImageOptim

画像の圧縮・最適化ツールです。:camera_with_flash:
Qiita等でアウトプットする際に画像サイズが大きいと制限にかかってアップロード出来ない!なんてときはImageOptimへドラッグ&ドロップする事で手軽にファイルサイズを軽減。

:point_right_tone4: Biscuit

アプリ一元管理ツール。
BiscuitにslackとかNotionとかInoreaderを食べさせて便利につかわせていただいております。
Stationよりも使いやすいし動作が軽い。あとロゴがかわいい:cookie:

:point_right_tone4: DeepL

翻訳ツール。:person_frowning_tone1:
一般的な翻訳ツールよりDeepLのほうが翻訳精度がよくてライブラリの公式ドキュメントとか、エラーの内容とかをこっちに移して読んだりしてる。
本当は英語がきちんと読めるようになればいいんだけどね。。英語学習コスト抑えたい方に...
DeepLを立ち上げている状態で翻訳したいテキストを選択状態にしてcommand + C(2回)でささっと起動してくれるとこがせっかちさんには便利な機能。

Kapture 2020-11-28 at 20.46.11.gif

:point_right_tone4: Inoreader

RSSリーダー。:eyes:
個人的にFeedlyより使いやすいし見やすいかな。
見た目の表示なんかも色々変えれる。おすすめはカードビュー。
スクリーンショット 2020-11-28 16.46.42.png

NitterでRSS化すればTwiiterから特定のユーザのRSS取得ができる。Nitterの使い方はこちらを参照してね。
あなたは知らないだろうけど、わたしはあなたのTweet...見てます...:eyes::eyes::eyes::eyes:

フロントエンドは技術の移り変わり、トレンドがバシバシ変わっていくのでリアルタイムな鮮度のいい情報をさくっと取得しときましょう。
この辺出来てないとフロントエンドは生きていかれへんのやで。節子。
アウトプットする時間はなかなか持ててないけどせめてインプットを...と心がけております。はい。

:point_right_tone4: Runcat

CPU使用率とかを可視化してくれるMac常駐アプリ。:cat:
ファンが回りまくってこのMac爆発するんじゃないか!!?って思ったら常駐アイコンが猛ダッシュして視覚的に教えてくれる。
更にここからアクティビティモニタを起動できるので不必要なプロセスを確認してkillすることで爆発を回避。
M1 Macはファンレスなのでファンの音がそもそも発生しない為、気が付かない内に爆発寸前だった!!なんて事がないためにも導入必須。
デザイナーさんとお友達だったら自分だけの特別なランナーもできちゃうかも!!?
わたしは魚男を使ってます。:relaxed: 「たかし」と名付けました。最近走りすぎて痩せてきたかも。
Kapture 2020-11-28 at 18.53.48.gif
スクリーンショット 2020-11-28 18.34.59.png

:point_right_tone4: Eagle

30日間無料だったかな?現在お試し中ですが便利です。:camera_with_flash:
デザイナーやディレクターとのやり取りをする上で、スクショを撮って見え方を伝えたりする事があるんですけど、
すぐデスクトップがゴミまみれになってしまうのでこいつは便利。とりあえずゴミスクショをぽいぽいーってdropして片付けれる。:wastebasket:
あとでEagle開いてゴミ達を一覧で見直せるしよきよきなツール。

■ ここから下はChrome拡張(Extension)

:point_right_tone4: React Developer Tools

Reactの開発デバッグ。

  • コンポーネントの構造を視覚的に把握できる
  • コンポーネント間で渡されているPropsの値が確認できる
  • Stateの値を確認できる
  • 実際に値を変えて動作の確認ができる

:point_right_tone4: Redux DevTools

Reduxの開発デバッグ。
どのActionでどの状態になり、Action実行後にStoreではどんな値になっているかが把握出来ます。
公式のDEMOページを見ていただければ確認出来ます。
DEMOではテキストを追加すればADD_TODOってアクションが実行されるし、テキストを編集すればEDIT_TODOってアクションが実行されているのが分かるかと。
実行前に準備する事としては下記をcreateStoreに渡して上げればOK!!:thumbsup_tone2:

 const store = createStore(
   reducer, /* preloadedState, */
+  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
 );

わたしはアイコンクリックしても出てくるWindowがちっこいので、アイコン右クリックしてopen in a panelを押して別窓で表示しながらテストしています。

:point_right_tone4: Web Vitals

CoreWebVitalsの数値が見れる。
「LCP」「FID」「CLS」早めに対処しておこう。うん。

:point_right_tone4: Material DevTools Theme Collection

ChromeのDevToolがイケイケになる。
好きなテーマはDraculaです。:smiling_imp:

手順

  • Material DevTools Theme Collectionを有効化する
  • ChromeDevToolsを開く
  • F1を押す
  • Settings > Preferences > Appearance > Theme を Dark に変更する
  • Settings > Experiments > Allow custom UI themes を有効にする

スクリーンショット 2020-11-28 20.10.19.png

いや、目が壊れそうwww

:point_right_tone4: Notion Web Clipper

Webクリッパー。
ぽちっとおしたらWebクリップしてくれる。
保存したい場所を変更したいときは、「Add To」から保存先の変更も可能。
Notion使ってるならまぁ入れてみてくれたまえよ。
のしょこTシャツをひそかに狙ってるけど常にSOLD OUT...
のしょーん(・-・ | N

ちなみに上で紹介しているBiscuitにNotionいれておくと色々と捗る。

:point_right_tone4: daily.dev

技術的なおすすめ記事をChromeのタブトップに出せる。
おしゃれな画像にする〜とかのExtensionはいっぱいあるけど、
エンジニアである以上、常に情報を収集する癖をつけるべし!!!:punch_tone1:
誰もあなたのおしゃれな画像の新規タブなんて興味ありませんし見てませんから!!
アプリ開発者であればAndroid DevelopersとかApple Developerとかは追加必須かな。
ただ、フィードに追加したいソースがdaily.dev上に無い場合はRSSを登録することができるんですが、無料会員の場合はdaily.devへのリクエストしかできません:sob:有料会員になれば追加することが可能。JSer.infoをリクエストしておきました。

:point_right_tone4: Gyazo

ブラウザ上のものをささっとキャプチャ。

:point_right_tone4: Grammarly for Chrome

Chrome上での英語の間違いを指摘してくれる。

■ まとめ

作業を効率化するアプリケーションを作る前に、まずは身近な作業効率化ツールを見つめ直してみるって事も大事かもしれませんね。
ツールはやがて古くなって廃れていき、より時代にあった便利な新しいツールがどんどん生み出されてユーザはそのツールに寄り添っていきます。
エンジニアのみなさん、ともに良い便利な世の中にしていきましょう。世の中めんどくさい事ばかりだ!!!
そんな事よりお仕事お仕事!!!

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

React Nativeのメリット・デメリット

はじめに

先日、React Nativeを使った個人開発アプリをリリースしました。
そこで、この記事ではReact Nativeでアプリを開発してみて良かった点、良くなかった点を紹介したいと思います。

「React Nativeを始めようかな」と考えている人の役に立つことができれば嬉しいです。

メリット❶ 学習コストが少ない

1つ目のメリットは学習コストが少なかったことです。
私は今回のアプリを開発する前は、JavaScriptのライブラリであるReactでWebアプリケーションの開発を行っていました。
React Nativeはコンポーネントの概念などReactと共通している部分が多いので、非常に開発に取り掛かりやすかったです。
Reactを使用してWebアプリケーションの開発を行っている方であれば、React Nativeの学習は参入障壁が非常に低く、取り組みやすいと感じます。

メリット❷ コードの修正が簡単

2つ目のメリットはコードの修正が簡単なことです。React Nativeは、ホットリロード機能があるため、自分が書いたコードを保存すれば、自動でリロードしてくれます。
例えば、UIを修正する際は変更したコードが瞬時に画面に反映されるため、スムーズに開発を進めることが出来ます。

メリット❸ 開発が効率的

3つ目のメリットは開発が効率的になることです。React Nativeは、クロスプラットフォームフレームワークであるため、iOSとAndroidのアプリを同時に開発することができます。この点はReact Nativeの大きな魅力であると感じました。

デメリット❶ エラーの解決や機能の実装に時間がかかる

続いてデメリットの紹介です。
1つ目のデメリットはエラーの解決や機能の実装に時間がかかることです。
個人的にReact Nativeは、エラーの解決や新しい機能を実装したいときに参考にするネット記事や資料が、他言語に比べて少ないと感じました。
そのため、アプリ開発中は英語の記事や資料を参考にする必要がありました。

デメリット❷ネイティブエンジニアには学習コストが高い

普段からネイティブ言語で開発しているエンジニアにとっては、1からJavaScriptを学習しなければいけないため、学習コストが高くなると考えられます。

まとめ

以上のように今回の記事では、私がReact Nativeでアプリを開発して感じたメリット・デメリットについて紹介しました。Reactの知識を使って、モバイルアプリケーションを開発できるという点が非常に素晴らしいと感じています。

ちなみに、今回私がリリースしたアプリはこちら

次回の記事では、実際に開発したアプリについて紹介してみようと思います!

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

Slackで投稿内容やファイルを閲覧するページを自作したお話 ①導入編

背景

Slackは非常に便利なコミュケーションツールなのですが、無料枠で使っていると閲覧上限1万件&ストレージ制限5GBが大きな制約となります。
自分の所属する団体では150人とかで使うので、1万件の制限があると3ヶ月分ぐらいしか閲覧できません。
(課金しろという話ですが、スタンダードプランにしても10万/月以上かかるので、、)

解決策??

ワークスペースを複数で運用したり、ログを取得するGASスプリクトをコピペして運用したりしていました。

参考) コピペのみ。Slackメッセージログを自動で保存する方法

問題点

ワークスペースを複数で運用すると、メッセージの共有ができないなど、コミュケーションツールとしての良さが失われてしまいます。また、GASスプリクトはログを残しておくという点では良いですが、後で閲覧するには不適です。

解決策: ログの取得や閲覧ページを自作する!

既存の方法で解決しないなら自分で作ってしまえ!という発想です。
とりあえず、

  • ログの取得・保存
  • 見やすい閲覧ページ

を実装しようと計画しました。

仕様

使用言語

  • React6.14.6
  • PHP7.4.4
  • MySQL5.7

フロントにはReact、バックエンドはPHPで実装しました。

Slackからデータを取得

SlackAPIでAppを作成してデータを取得します。APIを用いて以下のデータを取得しています。

  • ユーザー
  • チャンネル
  • チャット
  • ファイル

これらのデータはPHPで取得した後、MySQLでDBに格納します。

詳しくは別記事で説明します。

取得したデータを閲覧

フロントは勉強も兼ねてReactで実装しています。

また、DBに格納されたデータをフロントで取得するエンドポイントはPHPで作成しています。

詳しくは別記事で説明します。

まとめ

PHP+SlackAPIでデータ取得、MySQLでデータ格納して、PHPでエンドポイント作成、閲覧ページはReact+axiosという感じです。

編集後記

このシステムを作るのに、SlackAPIのドキュメントを何周もしました。
わからないところは、Google翻訳に助けられながらもなんとか理解できました。

続きの記事

時間あるときに書いていくので、気長にお待ち下さい、、

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

Reactでポートフォリオサイトを作ってみる by React初心者

はじめまして! Takuroと申します。

職業は静的Webページ制作がメインですが、最近はよりモダンな技術を使って
WebアプリケーションのUI/UX制作に挑戦したく、フロントエンド技術について勉強をはじめました。

一応、エンジニア未経験ではなく、組み込みソフトウェアSEとして1年ほど開発の実務経験があります。

Web開発をしていくに当たってアウトプットを積極的にしていくことが大切だと思ったので、
最初は自身の備忘録として記事を書いていこうと思います。

さて、今回はモダンなJSフレームワークのReactでポートフォリオサイトを作成した過程を書きます。

設計等は素人なりに考えていますが、現職の方からみると酷いものだと思います...
自分が成長した頃に「この頃は酷かったな」と笑い話にできるように記録しておきます?

もくじ

1.今回の開発環境
2.開発環境の構築
3.設計とファイル構成
4.実装
5.本番環境の用意とデプロイ
6.最後に

1. 今回の開発環境

ローカル環境

  • macOS Catalina 10.15.7
  • Docker 19.03.13
  • node 14.4.0
  • create-react-app
  • npm
  • git

本番環境

  • AWS Amplify
  • GitHub

使用ライブラリ

  • styled-components
  • material-ui
  • react-anchor-link-smooth-scroll

補足:選定理由

ローカル環境

Web開発環境ではスタンダードになりつつあるDockerで
勉強も兼ねて構築してみることにしました。

JSフレームワーク

Vue、Angular、Reactで迷いましたが、フロントエンドエンジニアの友人に
相談したところ、とりあえずReactをやっておけば応用が利くとのことでした。
自分でググってみても、VueはReactよりはとっつきやすいといった感じでしたので、
まずはReactをしっかり勉強しようと思いました。

styled-components

Web制作では主にSass + BEM記法でファイル分けをしていましたが、
Reactのコンポーネント思考にはCSS in JSが合っていると感じ、
新しい設計の勉強も兼ねて有名なstyled-componentsを選択しました。

2. 開発環境の構築

Dockerをインストールして、Reactアプリの開発環境を構築します。
今回はcrate-react-appで作成。
以下の記事を参考にさせていただきました。
https://qiita.com/2754github/items/413bdaaa90834e219dc8

3. 設計とファイル構成

今回かなり迷ってしまった部分です。Web制作の設計とは毛色が違うので戸惑いました。
ググってみてもいろいろなパターンがあり、?‍♂️?‍♂️?‍♂️といった状態。

結局、自分なりに分かりやすそうな構成で考えてみることにしました。

コンポーネント設計、ファイル分けはAtomic Designの考えを採用

AtomicDesignは簡単に言うとWebサイトをレゴブロックのようにパーツ分けしていく考え方です。
概念の理解は下記のURLを参考にさせていただきました。
https://qiita.com/yutaroadachi/items/3a8dca574ee140ac8099。

この考えを元にファイル分け、フォルダ分けをしていきます。

ファイル構成.png

正直今回の規模ではこの粒度の分け方をしなくても良いかもしれませんが、Reactのコンポーネント思考の
勉強のためにこんな感じで分けてみました。

CSSは各コンポーネントファイルに書く

CSS設計はCSS ModulesかCSS in JSかで迷いました。
WordPressサイト制作ではBEM記法を使っていたので、
感覚的にはCSS Modulesのほうが今までとギャップがなかったのですが、

  • コンポーネント思考に合わせる
  • スコープがある
  • クラス名を気にする必要がない

と言う点からCSS in JSのライブラリである
styled-componentsを採用してみることにしました。

使い方は以下のページが大変参考になりました。
https://watablogtravel.com/styled-components-with-react/

モバイルファーストでコーディング

最近はスマホユーザーが大半のためレスポンシブ対応が必須です。
スマホのスタイルをベースにタブレット用、PC用とスタイルを足していくことで
無駄な記述を減らすことを心がけました。

共通の値はjsファイルで定義してimport

これが良い方法かはわかりませんが、ブレイクポイントなどの共通の値は
jsファイルに定数として定義して各ファイルで読み込むようにしました。
正直、めんどくさいです...

Reduxを使うと良いのかもしれませんが、今回のポートフォリオがRexuxを使う規模では
ないということと、まずはピュアなReactを理解したいということもあり使用しませんでした。
概念は軽く勉強しましたが、今後より理解を深めていきたい所存です?

画像はassets/imagesからimport

create-react-appで作成したアプリでは画像はimportしないと表示されないようです。
publicフォルダに置けば、パス指定で表示できるようですが、ドキュメントではあまり推奨していないみたいです。
https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#using-the-public-folder

4. 実装

前項の設計をベースに実際にコーディングしていきます。
悩んだポイントとしてはコンポーネントのレイアウトスタイルの当て方。

コンポーネント自体にmerginや色などを指定してしまうと、使い回しが難しくなるという点から
Wrapperなどを作成して、そこにmarginを指定するわけですが、styled-componentsだとクラス名が
自動で振られるということもあり意外と悩みました。

結局、親コンポーネントにWrapprを作り、そこで子コンポーネントのレイアウト指定をしました。
色だけ変えたい場合などはpropsをで値を渡してスタイルが適用されるようにしまいた。
margenをpropsで渡す手もありますね。

<TextArea>
  <h4>{ this.state.skillName }</h4>
  <Text text={this.state.skillText} />
</TextArea>

//スタイル
const TextArea = styled.div`
    max-width: 300px;
    width: 100%;
    margin: 16px auto 0 auto;
    padding: 16px;
    background-color: #131A29;
    color:#fafafa;
    border-radius: 4px;
    border: 1px solid #fafafa;
    text-align: center;

  //子要素のスタイル
    h4 {
        color: skyblue;
    }

  //子コンポーネントのスタイル
    p {
        display: inline-block;
        text-align: left;
    }
`;

もっとスマートな方法がないか模索中です...

5. 本番環境の用意とデプロイ

実装がある程度完了したら、本番環境にデプロイしていきます。
今回は勉強も兼ねてAWSを使用してみることにしました。

とはいってもAWSは完全素人であり、現状あまりそちらの勉強をする時間がとれないので、
とりあえず「Aws Amplify」を利用してサクッと公開してみることに。

Amplifyの概念は以下の記事を参考にしました。
https://www.ragate.co.jp/blog/articles/684

今回はGitHubでコード管理をしていたので、連携してmasterブランチが更新されると
自動で検証、デプロイがされるようにできました。
以下の記事を参考にデプロイしました。
https://dev.classmethod.jp/articles/amplify-react-cicd-tutorial/

テストコードに関しては現状手が回っていませんが、今後勉強して書いていく予定です。

将来的にはEC2、S3、CodePipeline、CodeBuildなどで本格的な本番環境を
構築し、CI/CDがしっかり行えるようにしてきたいです。

6. 最後に

結構雑なまとめになってしまいました。間違いも多くあるかと思いますが、
今後は誰かの役に立てるよなアウトプットが
できるように精進していきたいと思います。

最後まで見ていただきありがとうございました。
それでは!

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

Reactで自己紹介サイトを作ってみる by React初心者

はじめまして! Takuroと申します。

職業は静的Webページ制作がメインですが、最近はよりモダンな技術を使って
WebアプリケーションのUI/UX制作に挑戦したく、フロントエンド技術について勉強をはじめました。

一応、エンジニア未経験ではなく、組み込みソフトウェアSEとして1年ほど開発の実務経験があります。

Web開発をしていくに当たってアウトプットを積極的にしていくことが大切だと思ったので、
最初は自身の備忘録として記事を書いていこうと思います。

さて、今回はモダンなJSフレームワークのReactで自己紹介サイトを作成した過程を書きます。

設計等は素人なりに考えていますが、現職の方からみると酷いものだと思います...
自分が成長した頃に「この頃は酷かったな」と笑い話にできるように記録しておきます?

もくじ

1.今回の開発環境
2.開発環境の構築
3.設計とファイル構成
4.実装
5.本番環境の用意とデプロイ
6.最後に

1. 今回の開発環境

ローカル環境

  • macOS Catalina 10.15.7
  • Docker 19.03.13
  • node 14.4.0
  • create-react-app
  • npm 6.14.4
  • git 2.24.3

本番環境

  • AWS Amplify

コード管理

  • GitHub

使用ライブラリ

  • styled-components
  • material-ui
  • react-anchor-link-smooth-scroll

選定理由

ローカル環境

Web開発環境ではスタンダードになりつつあるDockerで
勉強も兼ねてローカル環境を構築してみることにしました。

JSフレームワーク

Vue、Angular、Reactで迷いましたが、フロントエンドエンジニアの友人に
相談したところ、とりあえずReactをやっておけば応用が利くとのことでした。
自分でググってみても、VueはReactよりはとっつきやすいといった感じでしたので、
まずはReactをしっかり勉強しようと思いました。

styled-components

Web制作では主にSass + BEM記法でファイル分けをしていましたが、
Reactのコンポーネント思考にはCSS in JSが合っていると感じ、
新しい設計の勉強も兼ねて有名なstyled-componentsを選択しました。

2. 開発環境の構築

Dockerをインストールして、Reactアプリのローカル開発環境を構築します。
今回はcrate-react-appで作成。
以下の記事を参考にさせていただきました。
https://qiita.com/2754github/items/413bdaaa90834e219dc8

3. 設計とファイル構成

今回かなり迷ってしまった部分です。Web制作の設計とは毛色が違うので戸惑いました。
ググってみてもいろいろなパターンがあり、?‍♂️?‍♂️?‍♂️といった状態。

結局、自分なりに分かりやすそうな構成で考えてみることにしました。

コンポーネント設計、ファイル分けはAtomic Designの考えを採用

AtomicDesignは簡単に言うとWebサイトをレゴブロックのようにパーツ分けしていく考え方です。
概念の理解は下記のURLを参考にさせていただきました。
https://qiita.com/yutaroadachi/items/3a8dca574ee140ac8099。

この考えを元にファイル分け、フォルダ分けをしていきます。

ファイル構成.png

正直今回の規模ではこの粒度の分け方をしなくても良いかもしれませんが、Reactのコンポーネント思考の
勉強のためにこんな感じで分けてみました。

CSSは各コンポーネントファイルに書く

CSS設計はCSS ModulesかCSS in JSかで迷いました。
WordPressサイト制作ではBEM記法を使っていたので、
感覚的にはCSS Modulesのほうが今までとギャップがなかったのですが、

  • コンポーネント思考に合わせる
  • スコープがある
  • クラス名を気にする必要がない

と言う点からCSS in JSのライブラリである
styled-componentsを採用してみることにしました。

使い方は以下のページが大変参考になりました。
https://watablogtravel.com/styled-components-with-react/

モバイルファーストでコーディング

最近はスマホユーザーが大半のためレスポンシブ対応が必須です。
スマホのスタイルをベースにタブレット用、PC用とスタイルを足していくことで
無駄な記述を減らすことを心がけました。

共通の値はjsファイルで定義してimport

これが良い方法かはわかりませんが、ブレイクポイントなどの共通の値は
jsファイルに定数として定義して各ファイルで読み込むようにしました。
正直、めんどくさいです...

Reduxを使うと良いのかもしれませんが、今回のポートフォリオがRexuxを使う規模では
ないということと、まずはピュアなReactを理解したいということもあり使用しませんでした。
概念は軽く勉強しましたが、今後より理解を深めていきたい所存です?

画像はassets/imagesからimport

create-react-appで作成したアプリでは画像はimportしないと表示されないようです。
publicフォルダに置けば、パス指定で表示できるようですが、ドキュメントではあまり推奨していないみたいです。
https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#using-the-public-folder

4. 実装

前項の設計をベースに実際にコーディングしていきます。
悩んだポイントとしてはコンポーネントのレイアウトスタイルの当て方。

コンポーネント自体にmerginや色などを指定してしまうと、使い回しが難しくなるという点から
Wrapperなどを作成して、そこにmarginを指定するわけですが、styled-componentsだとクラス名が
自動で振られるということもあり意外と悩みました。

結局、親コンポーネントにWrapprを作り、そこで子コンポーネントのレイアウト指定をしました。
色だけ変えたい場合などはpropsをで値を渡してスタイルが適用されるようにしまいた。
margenをpropsで渡す手もありますね。

<TextArea>
  <h4>{ this.state.skillName }</h4>
  <Text text={this.state.skillText} />
</TextArea>

//スタイル
const TextArea = styled.div`
    max-width: 300px;
    width: 100%;
    margin: 16px auto 0 auto;
    padding: 16px;
    background-color: #131A29;
    color:#fafafa;
    border-radius: 4px;
    border: 1px solid #fafafa;
    text-align: center;

  //子要素のスタイル
    h4 {
        color: skyblue;
    }

  //子コンポーネントのスタイル
    p {
        display: inline-block;
        text-align: left;
    }
`;

もっとスマートな方法がないか模索中です...

5. 本番環境の用意とデプロイ

実装がある程度完了したら、本番環境にデプロイしていきます。
今回は勉強も兼ねてAWSを使用してみることにしました。

とはいってもAWSは完全素人であり、現状あまりそちらの勉強をする時間がとれないので、
とりあえず「Aws Amplify」を利用してサクッと公開してみることに。

Amplifyの概念は以下の記事を参考にしました。
https://www.ragate.co.jp/blog/articles/684

今回はGitHubでコード管理をしていたので、連携してmasterブランチが更新されると
自動で検証、デプロイがされるようにできました。
以下の記事を参考にデプロイしました。
https://dev.classmethod.jp/articles/amplify-react-cicd-tutorial/

テストコードに関しては現状手が回っていませんが、今後勉強して書いていく予定です。

将来的にはEC2、S3、CodePipeline、CodeBuildなどで本格的な本番環境を
構築し、CI/CDがしっかり行えるようにしてきたいです。

6. 最後に

結構雑なまとめになってしまいました。間違いも多くあるかと思いますが、
今後は誰かの役に立てるよなアウトプットが
できるように精進していきたいと思います。

最後まで見ていただきありがとうございました。
それでは!

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