iOSエンジニアのつぶやき

毎朝8:30に iOS 関連の技術について1つぶやいています。まれに釣りについてつぶやく可能性があります。

JavaScriptのimportを調べた

JSのimportって?

import 文は、他のモジュールによってエクスポートされた読み込み専用のライブバインディングをインポートするために使用します。

ライブバンディングとは、バインディングをエクスポートしたモジュールによって値が更新されることを指すそうです。

種類

下記のようなimportの種類があります。

import defaultExport from "module-name";
import * as name from "module-name";
import { export1 } from "module-name";
import { export1 as alias1 } from "module-name";
import { export1 , export2 } from "module-name";
import { foo , bar } from "module-name/path/to/specific/un-exported/file";
import { export1 , export2 as alias2 , [...] } from "module-name";
import defaultExport, { export1 [ , [...] ] } from "module-name";
import defaultExport, * as name from "module-name";
import "module-name";
var promise = import("module-name");

参照: https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/import#syntax

import defaultExport from "module-name";

まずはこれ。モジュールからデフォルトのエクスポートをインポートしています。

デフォルトエクスポートは、モジュール側で下記のように設定されていて、何も指定しない場合にインポートされます。

export default expression;

import * as name from "module-name";

モジュール内の全てのエクスポートをインポートします。それぞれのエクスポートにアクセスするには下記のようにします。

name.hoge()

import { export1 } from "module-name";

モジュール内にあるexport1というエクスポートをインポートします。

import { export1 as alias1 } from "module-name";

モジュール内にあるexport1というエクスポートをalias1という名前に変更してインポートします。

import { export1 , export2 } from "module-name";

モジュールからexport1export2の二つのエクスポートをインポートします。

import defaultExport, * as name from "module-name";

デフォルトエクスポートをnameという名前に変更してインポートします。

import "module-name";

モジュールのグローバルコードを実行するためだけに、使われるみたいです👀実際にインポートはされないらしい。

var promise = import("module-name");

ロード時にインポートしたいモジュールが存在しない場合などの理由で、動的にインポートを行いたい時に使うらしいです。

という感じで本日は以上🍺

参考

developer.mozilla.org

その他の記事

yamato8010.hatenablog.com

yamato8010.hatenablog.com

yamato8010.hatenablog.com

コマンドでAndroidプロジェクトを開く

本日はAndroid StudioのTipsを紹介します👷‍♀️

Terminalでプロジェクトのルートにいるとき、vscodecode .コマンドのように、プロジェクトを開きたい時ってありますよね。 そんな時、Android Studioでは studio .コマンドが使えます。ちなみに、デフォルトでは、コマンドラインが設定されていないので、Tools > Create Command-line Launcher..でコマンドのパスを通して、使えるようにします。

f:id:yum_fishing:20210530195556p:plain

これで、プロジェクトのルートからstudio .を実行することで、プロジェクトが開くようになります🎉

てな感じで本日も以上となります🍺

その他の記事

yamato8010.hatenablog.com

yamato8010.hatenablog.com

yamato8010.hatenablog.com

【React】Class Component と Functional Component

React勉強中なので、簡単にClass ComponentFunctional Componentの違いをメモしておきます👷‍♀️

Class Component

Class ComponentはStateやライフサイクルを持つことができます。実装クラスはReact.Componentを継承する必要があります。

class Summary extends React.Component {
}

ライフサイクルメソッドを使って、コンポーネントの再レンダリングをするかどうかをハンドリングしたい場合は、shouldComponentUpdateというメソッドをクラスに実装します。 詳しい他のライフサイクルメソッドについては、下記の記事がわかりやすかったので、載せておきます。

qiita.com

Functional Component

Functional Componentはその名の通り関数なので、Class Componentとは異なりStateやライフサイクルを持ちません。ただ、その分コンポーネントの記述を簡潔にすることができます。

const Hoge: React.FC<Props> = props => {
}

今までは、Functional Componentよりも高機能なClass Componentを使うことが主流だったようですが、React Hooksが導入されたことにより、Functional Componentでもクラスと同じようにState(状態)が持てるようになり、現在はFunctional Componentが主流になっているそうです。

ja.reactjs.org

React Hooksは、Functional Componentに対して、状態を保存するための変数領域を提供することで状態を保つことを実現しているようです。 公式ドキュメントに載っているコードをお借りして、見てみます。const [count, setCount] = useState(0); で定義しているcountは値(State)を、setCountは値を更新するための関数をそれぞれ定義しています。ちなみにサンプルコードではuseStateを使って初期値を0に設定しています。という感じでReact Hooksは、Functional ComponentでシンプルにStateの読み書きをできるようにしたもののようですね👀

import React, { useState } from 'react';

function Example() {
  // Declare a new state variable, which we'll call "count"
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

てな感じで本日も以上となります🍺

参考

その他の記事

yamato8010.hatenablog.com

yamato8010.hatenablog.com

yamato8010.hatenablog.com

【React】Parsing error: JSX expressions must have one parent elementというのに出くわした

最近React入門したので、Webフロント周りも記事にしていこうと思います👷‍♀️

結論

JSXで下記のようなものを書いてたら、エラーに出くわした。

  public render() {
    return (
      <div>
        hoge
      </div>
      <div>
        hoge
      </div>
    )
  }

Parsing error: JSX expressions must have one parent element

どうやら、JSXでは二つの要素を返却することができないっぽいですね。ということで、下記のように修正。React.Fragmentは複数の要素をグルーピングするためのタグで、HTMLのタグとしては出力されないので、<div>でまとめるよりスマートに書くことができます。

  public render() {
    return (
      <React.Fragment>
        <div>hoge</div>
        <div>hoge</div>
      </React.Fragment>
    )
  }

てな感じで本日は以上となります🍺

参考

その他の記事

yamato8010.hatenablog.com

yamato8010.hatenablog.com

yamato8010.hatenablog.com

【30C】なんとなく使っていたCloud Functionsをちゃんと調べてみた Part1

Cloud Functionsとは?

Cloud Functionsは、Firebaseプロジェクトのデータベース(Realmtime Database or Firestore)でのイベントやHTTPSリクエストなどをトリガーにバックエンドのコードを自動的に実行するための機能です。また、トラフィックが増えた場合にもCloud Functionsはオートスケールするのでサーバを管理するコストが省けます。

関数はどのようにデプロイされるのか?

Cloud Functionsでは、それぞれのトリガーごとに関数を定義することでバックエンドコードを実行させます。例えば、Firestoreの特定のコレクションにドキュメントが追加された場合の関数は下記のようになります。

exports.onUserLikeCreated = functions.firestore.document(`collections/{collectionId}/`).onCreate(async (snap, context) => {
    // ドキュメントが追加された時の処理
});

関数がFirebaseCLIにデプロイされる時、コードから.zipが作成され、Cloud Storageバケットにアップロードされます。アップロードが完了すると、Cloud BuildというGCPのインフラストラクチャでビルドを行う仕組みによって、関数がビルドされます。ビルドが完了するとコンテナイメージが、非公開のContainer Registry リポジトリに展開されます。これにより、コードをクライアントから隔離することができます。

てな感じで続きはまた次回🍺

その他の記事

yamato8010.hatenablog.com

yamato8010.hatenablog.com

yamato8010.hatenablog.com

【Firebase】Next.jsをCloudFunctionsでホストさせる

next.jsにサンプルがあるので、これを使っていきます!

github.com

まずは、サンプルをインストールします。ちなみにAPP-NAMEは、よしなに変えてください。今回はnpmで作業します。ちなみにyarnがない場合は、yarnpkg install has failed.的なエラーが出るので、npm i -g yarnyarnをインストールします。

$ npx create-next-app --example with-firebase-hosting APP-NAME

次に、.firebasercdefaultを任意のFirebaseプロジェクトIDに置き換えます。

{
  "projects": {
    "default": "project-id"
  }
}

パッケージのdependenciesをインストールして、npm run devでローカルでアプリを実行してみましょう👷‍♀️

$ npm install
$ npm run dev

また、デプロイなどもnpm経由でやります。

$ npm run deploy

てな感じで、とりあえずCloudFunctionsにNext.jsアプリをホストすることができました🍺

参考

その他の記事

yamato8010.hatenablog.com

yamato8010.hatenablog.com

yamato8010.hatenablog.com

【RxSwift】ScrollViewのContentSizeの変更通知を受け取る

結論

下記のようにKVOでcontentSizeを取得することができます。ちなみにこの状態で返る値はObservable<CGSize?>になります。

scrollView.rx.observe(CGSize.self, "contentSize") // Observable<CGSize?>

今回は、heightのみでいいのと、アンラップした状態で値をリッスンしたいので、下記のようにしました。

scrollView.rx.observe(CGSize.self, "contentSize").compactMap { $0?.height } // Observable<CGFloat>

てな感じで本日も以上となります🍺

その他の記事

yamato8010.hatenablog.com

yamato8010.hatenablog.com

yamato8010.hatenablog.com