- 投稿日:2019-06-25T23:00:42+09:00
bind(バインディング)の概念について(Rxswift)
bind(バインディングってそもそも何)
Rxswiftの.bindなどで用いられるバインディングですがプログラムに置き換えると結局どういうことなの?
と感じたのでまとめました
・バインディングは.bindしなくてもそもそもできるもの
・Timer
と似たようなもんで監視対象が時間ではなくViewなどになった
だけ// 1秒'たったら'getInfoを実行する let timerGetInfo = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(getInfo), userInfo: nil, repeats: true) timerGetInfo.fire()// hugaを満たしたらhogeにバインディング .map { huga } .bind(to: hoge)・まぁ用は
紐付ける
ぐらいに考えとけばいい
→深く掘り下げすぎなくても分からなければならなくなってからやってったらいい、キャリア積んだ人でもこの辺のことは探り探りで進めていくことも多い結論
あんま気にすんな
- 投稿日:2019-06-25T23:00:42+09:00
bind(バインディング)の概念について(Rxswift)(kboy流)
bind(バインディングってそもそも何)
Rxswiftの.bindなどで用いられるバインディングですがプログラムに置き換えると結局どういうことなの?
という疑問がググってもなかなか消化できずkboyさんにお聞きしたところ
・バインディングは.bindしなくてもそもそもできるもの
・Timer
と似たようなもんで監視対象が時間ではなくViewなどになった
だけ// 1秒'たったら'getInfoを実行する let timerGetInfo = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(getInfo), userInfo: nil, repeats: true) timerGetInfo.fire()// hugaを満たしたらhogeにバインディング .map { huga } .bind(to: hoge)・まぁ用は
紐付ける
ぐらいに考えとけばいい
→深く掘り下げすぎなくても分からなければならなくなってからやってったらいい、キャリア積んだ人でもこの辺のことは探り探りで進めていくことも多い結論
あんま気にすんな
kboyさん
ARKit開発は国内トップの凄腕iOSエンジニア
MENTAというサービス内でiOSアプリ開発のメンターをされています(1万円/月)
- 投稿日:2019-06-25T19:49:10+09:00
React.js勉強中に気になった些細なこと
なんやねん
React.jsの勉強中に気になった部分
サンプルコードは公式から誰でも見れるし内容についての話じゃないので大丈夫だと思うけど怒られたら消しますほんで?
<script type="text/babel"> let dom = document.querySelector('#root'); let message = 'お名前は?:'; let nameVal = ''; let doChange = (event)=>{ nameVal = event.target.value; message = 'こんにちは、' + nameVal + 'さん'; }; let doAction = (event)=>{ let element = ( <div> <p>{message}</p> <div> <input type="text" id="input" onChange={doChange} /> <button onClick={doAction}> クリック </button> </div> </div> ); ReactDOM.render(element, dom); }; doAction(); </script>ふむふむ
クリックイベントのサンプルですね
ん?
<input type="text" id="input" onChange={doChange} /> <button onClick={doAction}> クリック </button>ここの部分
クリックイベントでレンダリングしてるけど、onChange(inputの中身を変更する)のたびにレンダリングするように変えればそうなるって理解でOKだよね(イベントだから)・・・
確かめずにはいられない!!
let doAction = (event)=>{ nameVal = event.target.value; message = 'こんにちは、' + nameVal + 'さん'; let element = ( <div> <p>{message}</p> <div> <input type="text" id="input" onChange={doAction} /> <button onClick={doAction}> クリック </button> </div> </div> ); ReactDOM.render(element, dom); };確かめるだけならこれでOKかな、確かめよう
よし、onChangeのたびに表示が変わった!
スッキリ!!そんな、ほぼ日記のような些細なこと
- 投稿日:2019-06-25T18:44:31+09:00
jQuery世代がReact+OpenAPIでSPAを作ってみた感想
jQuery世代がReactでSPAを作ってみた感想
ここ数年サーバーサイド専任だったので、知識としては知っていても経験はjQueryで止まっていたのですが、色々あってReactでSPAを作ることになりました。
何とかおっかなびっくり作り終えたわけですが、発想の転換を色々と迫られたので感想でも。ちなみに成果物は社内用システムなので具体的なソースの公開についてはご容赦を
Component
かつてのjQuery時代と言うと、コンポーネントはjQueryUIくらいしかなく、
基本的に画面はゴリゴリとhtmlとcssを書いて作るものでした。
ロジックの側でもDOMを書き換えたりクラスを付け替えたりするのは日常茶飯事でした。
例えば、jQuery時代に入力値をチェックしてInputにエラーを付ける場合$(selector).addClass('error');みたいな感じでした。(しかもこんなクラス名の付け方をしていたら衝突しまくってひどい目に会っていたでしょう。)
それが、今の時代基本的に基準はComponentです。
自分でhtmlを書くなんて言うのはComponent自体を実装する場合くらいで、
ロジック内ではstateを書き換えるだけです。
例えば、前述のようなエラーを付ける場合にはstateにエラーを渡すだけです。component.setState({ isError:true });始めは戸惑いましたが、コンポーネントの範囲内だけのスタイルも簡単にかけて影響度も小さくて済みますし、いい時代になったものだなと思います。
DOM操作のコストをあまり考えなくていい
ブラウザの平均的性能が上がったことと、VirtualDomのおかげでDOM操作のコストをあまり考えなくてよくなったのもありがたいと感じる部分でした。
スクロールで延々DOMが足され続けるとか明らかなアンチパターン実装をしない限りここでストレスを感じなくていいのはちょっと感動です。
某ブラウザの古いバージョンとかは本当にちょっと触るだけで固まりやがりましたので。APIだけ決めてフロントとサーバーサイドで作業分担してみた
折角SPAで作ることに決めたので、OpenAPIでAPIの仕様だけ決めて、サーバーサイドとフロントエンドで別々に作って、ある程度できてから組み合わせるというのもやってみました。
これが、予想外に快適でした。
始めは実際に組み合わせたらエラーばっかりだろうなぁと思っていましたが、きちんと決めていただけあってAPI仕様上のエラーはほぼなく繋がりました。(トラブルが起こったのはAPI定義外の認証周りだけ)
二人で作業をしていたのですが、完全に触る場所がずれているのでコードのConflictもなく、Mockサーバーや自動テストベースで開発が進むのでオーバーヘッドがかなり少なかったように思えます。エコシステムの発達がすごい
ReactやVue,Angularといったメジャーどころのフレームワークは、CLIからwebpack組み込みのプロジェクトを作るのが当たり前で、yarnやnpmのコマンドをちょっと打てば必要なプラグインやライブラリは簡単に組み込めるようになっていますし、ビルドや開発サーバーの立ち上げも一発です。
かつて頑張ってscriptタグを書きまくって、自分で依存性制御していた時代から考えると嘘のようです。ただ、色々なところを隠蔽してしまっているという面もあるので、何となくでもそれなりに書けるようになってはいますが、きちんと分かっている人とそうではない人の差が広がっているのかも知れません。
どんどん抽象化と分割が進んでいる
今回はそこまで大きくないプロダクトだったのでReduxは使わなかったのですが、より大規模になってstate管理が複雑になると確かに直接stateを弄っていられなくなるんだろうなと感じました。
やはり大規模化⇒より抽象化されて分割されるという図式はどのレイヤーでも変わらないようです。まとめ
- 10年分くらい一気に歴史を進めて見たが非常に楽しかった
- 発想の転換は迫られるものの何とかなる
- フロント屋さん以外も触ってみるといいと思います。
- 投稿日:2019-06-25T17:30:41+09:00
React + IPFS + Ethereum で簡単なイメージアップローダーを作成する
はじめに
React + IPFS + Ethereumで簡単なイメージアップローダーを作成します。
基本的なことは省いて要所だけを書いてるのでつずいたところがあればコメントください!1. 環境構築
簡単に環境設定をしてくれる、truffleが提供するreact unboxを利用します。
$ mkdir ipfs_image_uploader $ cd ipfs_image_uploader $ truffle unbox reactGanacheをインストール( https://www.trufflesuite.com/ganache )して起動します。
そしてローカルのブロックチェーンにコントラクトをデプロイします$ truffle compile $ truffle migrate --reset
react unbox
ではフロントエンドはclient
ディレクトリにあります。$ cd client $ npm startこのような画面が開いたら
react unbox
での環境設定は成功です。2. コントラクト
SimpleStorage.sol
のコントラクトを下記のように書き換えます。
簡単な説明をコメントアウトで書きました//SimpleStore.sol pragma solidity ^0.5.0; contract SimpleStorage { string ipfsHash; //Ipfsいう構造体を作り、その中にはipfsのHash値が入ります struct Ipfs { string _ipfsHash; } //上記で作成したIpfs構造体を配列として格納できるIpfsHashを作ります。 Ipfs[] public IpfsHash; // set関数でフロントからipfsのハッシュ値が渡されます function set(string memory _ipfsHash) public { ipfsHash = _ipfsHash; //Ipfs(ipfsHash)で渡されたHash値こ構造体に格納し、構造体の配列であるIpfsHashにpushします IpfsHash.push(Ipfs(ipfsHash)); } //ipfsのHash値を取り出す関数 function get() public view returns (string memory) { return ipfsHash; } //構造体の配列の大きさを取得する関数。フロントで使用します function arraylength() public view returns (uint) { return IpfsHash.length; } }コントラクトを書き終えたらサイドデプロイします。
$ truffle migrate --reset3. IPFS
インスタンスを作成、ipfsファイルを読めるようにするJSライブラリをインストールします。
$ npm install ipfs-apiインストールが終了したら
ipfs.js
をApp.jsと同じディレクトリに作成し、このようなコードを書きます。ipfs.jsconst IPFS = require('ipfs-api'); const ipfs = new IPFS({host:'ipfs.infura.io', port: 5001, protocol: 'https'}); export default ipfs;INFURAを利用することによりIPFSのノードに自動的に繋げてくれるようになるそうです。
これでIPFSに繋がるようになりました。4.フロント
App.js
を以下のように書き換えます。App.jsimport React, { Component } from "react"; import SimpleStorageContract from "./contracts/SimpleStorage.json"; import getWeb3 from "./utils/getWeb3"; import ipfs from "./ipfs.js"; import "./App.css"; class App extends Component { constructor(props) { super(props) this.state= { web3: null, accounts: null, contract: null, buffer: null, ipfsHash: [], hoge: '', } //関数を使えるようにする this.captureFile = this.captureFile.bind(this); this.onSubmit = this.onSubmit.bind(this); this.loadIpfsHash = this.loadIpfsHash.bind(this) } componentWillMount = async () => { try { // Get network provider and web3 instance. const web3 = await getWeb3(); // Web3でユーザーのアドレスを取得 const accounts = await web3.eth.getAccounts(); // コントラクト情報をブロックチェーン上から取得 const networkId = await web3.eth.net.getId(); const deployedNetwork = SimpleStorageContract.networks[networkId]; //コントラクトを定義する const instance = new web3.eth.Contract( SimpleStorageContract.abi, deployedNetwork && deployedNetwork.address, ); //Stateにweb3, accounts, contractをセットする this.setState({ web3, accounts, contract: instance }, this.runExample); } catch (error) { alert(`Failed to load web3, accounts, or contract. Check console for details.`,); console.error(error); } await this.loadIpfsHash(); }; loadIpfsHash = async () => { const length = await this.state.contract.methods.arraylength().call() for (var i = 0; i <= length; i++) { const ipfsHashs = await this.state.contract.methods.IpfsHash(i).call() this.setState({ ipfsHash: [...this.state.ipfsHash, ipfsHashs] }) } } captureFile(event) { console.log('File loader ...') event.preventDefault() //fileにアクセスする const file = event.target.files[0] //fileを読み込む const reader = new window.FileReader() //fileをipfsにアクセスできるArrayに追加する reader.readAsArrayBuffer(file) reader.onloadend = () => { //結果をBufferに入れ,ipfsにアクセスできるようにする this.setState({ buffer: Buffer(reader.result) }) console.log('buffer', this.state.buffer) } } onSubmit = async (event) => { console.log('on Submit ...') //Submit時にリロードしなくなる event.preventDefault() //ipfsにファイルを追加 ipfs.files.add(this.state.buffer, async (error, result) => { if(error) { console.error(error) return } //ブロックチェーンにipfsHashを書きこむ this.state.contract.methods.set(result[0].hash).send({ from: this.state.accounts[0] }) //iphsHashの値をアップデートする return this.loadIpfsHash(); }) } render() { if (!this.state.web3) { return <div>Loading Web3, accounts, and contract...</div>; } return ( <div className="App"> <h1>Your Image</h1> <p>This image is stored on IPFS & The Ethereum Blockchain!</p> {this.state.ipfsHash.map((hash, key) => { return( <div key={key}> <img src= {`https://ipfs.io/ipfs/${hash}`} alt=""></img> </div> ) })} <h2>Upload image</h2> <form onSubmit={this.onSubmit} > <input type="file" onChange={this.captureFile} /> <input type="submit" /> </form> </div> ); } } export default App;captureFile()
captureFile()
の関数で、アップロードしたデータをIPFSに追加できるようにしています。onSubmit()
onSubmit()
の関数でIPFSとブロックチェーンにそれぞれ書き込んでいます。
ipfs.files.add()
でIPFSにアップロードしたファイルを追加しています。
そしてthis.state.contract.methods.set(result[0].hash)
にてIPFSのハッシュ値をブロックチェーンに書き込んでいます。5. 終わりに
意外と簡単にIPFSを使うことができました。
何かわからないこと、また間違い等ありましたらコメントいただけると幸いです。GitHubはこちらです
参考サイト
Dapp University
基本的にはこのサイトもとにして、少し付け加える形で作成しました。
- 投稿日:2019-06-25T16:57:09+09:00
Reactでポートフォリオサイト作り直した
大したことはしていない元々あったシンプルなポートフォリオサイトReactで組み直した。
github
https://github.com/taichi0514/profile-v3ホスティング
https://codeworks.site/Reactの考えとして親コンポーネントに処理させて子コンポーネントでレンダリングさせるものなので
処理が発生するものは親コンポーネントでstateで持っておいて子コンポーネントにporpsで渡した。
top.js
class Top extends React.Component { constructor(props) { super(props); this.state = { text: [], age: [] }; } componentDidMount() { const GasUrl = "GASのURL" axios .get(GasUrl) .then((response) => { const text = response.data; this.setState({text: text}); }) .catch(function (error) { console.log(error); }) function age(y, m, d) { const birth = moment().year(y).month(m - 1).date(d); return moment().diff(birth, 'years'); } this.setState({age: age(1994,5,14)}); } render(){ return( <div className="contents"> <Profile title={"プロフィール"} age={this.state.age}/> <Introduction title={"自己紹介"} /> <Goal title={"やりたいこと"} /> <Doing title={"やっていること"} /> <Important title={"仕事で大切にしていること"} /> <Tool title={"仕事で使っている言語・ツール"} /> <Web title={"プライベート制作"} text={this.state.text}/> <Link title={"リンク"} /> </div> ) } } export default Top;
web.js
import React from 'react'; class Web extends React.Component { render(){ return( <section className="web"> <h2>{this.props.title}</h2> <ul> {this.props.text.map((text, i) => <li key={i}><a href={text.Url}>{text.Title}</a></li>)} </ul> </section> ) } } export default Web;
profile.js
import React from 'react'; import '../scss/profile.scss'; class Profile extends React.Component { render(){ return( <section> <h2>{this.props.title}</h2> <div className="profile_inner"> <dl> <dt>名前</dt> <dd>村井大地</dd> </dl> <dl> <dt>年齢</dt> <dd>{this.props.age}歳</dd> </dl> <dl> <dt>在住地</dt> <dd>東京</dd> </dl> <dl> <dt>職種</dt> <dd>フロントエンドエンジニア</dd> </dl> </div> </section> ) } } export default Profile;処理一覧
- google spreadsheetからgasでjsonを吐き出してレンダリングさせる
- 年齢計算する
google spreadsheetからgasでjsonを吐き出してレンダリングさせる
しょうもない文言変更の際いちいちコミットするのが面倒だったので
プライベート制作
のみjsonレンダリングする形にしている
ツール
,リンク
もjsonレンダリングしようと思ったがそんなに更新しないのでやめておいた
参考記事
https://qiita.com/belowt/items/ee6dedff45f9d9e58ef4年齢計算する
地味に年を取ったときに情報更新するのがめんどかったので関数で処理することにしました。
propsでカスタマイズした箇所
h2要素にはすべてprorpで値を渡してレンダリングさせています。
タイトルの値は変わりますが要素とスタイルは変わらないのでprorpsの使い道かなと思いこんな感じにしました。一年ぶりのReactでほぼすべて忘れていたReactを頭に刷り込ませるため書き起こしました。
レビュー、指摘等があればコメントください
- 投稿日:2019-06-25T14:09:29+09:00
React redux-tutorial お手軽環境構築
表題どおり
少しだけreactに慣れてきてそろそろ、次のモダン開発を求めてreduxを触ろうと、いい方法はないかと模索したところ
https://redux.js.org/basics/example
頼れる公式tutorial
とても詳しい日本語解説
https://qiita.com/xkumiyu/items/9dfe51d2bcb3bdb06da3さてはじめっか、と思ったところで
あれ、環境構築の説明だいぶはぶかれてんじゃーん・・・omg色々調べた結果
wbpackegeをコピペしてくるのも考えたけど
create-react-appにreduxをぶち込むことに$ mkdir practice $ cd practice $ npm i -g create-react-app $ create-react-app redux-practice $ cd react-redux $ npm start // しなくてもいいけど確認ここまでは普通のcreate-react-app
OKいつものやつがクルクル回っている。ここreduxの導入
$npm i react-redux redux/srcの中身をindex.js以外削除
/publicもindex.html以外削除これで環境はおk
あとはtutorialに従っていきましょう
- 投稿日:2019-06-25T09:32:22+09:00
ブラウザBiscuitの開発で得た知見その1 - プロトタイプ/本実装/Electron
Biscuitというブラウザを趣味で開発していまして、先日1.0を無事リリースしました。Biscuitの開発の中で得た技術的な知見を何回かに分けて共有していきたいと思います。
Biscuitって?
複数のアプリをまとめて管理して利用できるブラウザです。Windows、Mac、Linuxに対応しています。同種のアプリとしてはStationやFranz、Ramboxなどがあります。
特徴は、アプリをグルーピングでき視認性が高い点と、アプリごとにクッキーやローカルストレージなどが隔離され、プライベートブラウジングと同じ状態になる点です。これにより、複数アカウントを同時に運用できます。また、アカウントが入れ替わってしまって誤爆したりするミスも起こりにくくなります。
その他の特徴はダウンロードサイトをごらんください。
プロトタイプフェーズ
最初、Electron上でVue.jsを使ってプロトタイプを作成しました。Vueを選んだのは以前から使い慣れていて、手早く実装ができるという理由からです。
プロトタイプフェーズの目的は、プロダクトのMVP(Minimum Viable Product: 最低限の価値を持った製品)の検証とMVPを実現性を担保するための技術検証でした。なのでMVPに関係のない新しい技術の導入はあえて我慢しました。ブラウザなのでどうしても新しい技術も触る必要がありますが、このフェーズでは最低限に抑えることができたと思います。
プロトタイプフェーズでは以下の点について検証しました。
- 便利なブラウザを作ることは可能なのか?
- 良いユーザー体験を実現できるか?
- 素早く動作するか?(できればChromeと遜色ないレベルで動作してほしい)
- 技術検証
- 複数のWebViewをタブで切り替えて動作可能か?
- それぞれのタブでセッション情報などを隔離可能か?
実際にプロトを作ってみて、上記の点について問題がないことがわかりました。プロトにかけたのは3日間ぐらいでした。作りながら、実際に自分で使ってみて「便利かどうか?」という点もドッグフーディングしていきました。
本実装フェーズ
プロトで有用性、実現性が確認できたので、本格的に開発することにしました。
本実装では React/Redux/Typescrptを使いました。凝り始めるとある程度の大きさのアプリになるのが予想できましたし、プロトで技術的な基本部分はクリアできていたので、新しい技術要素を入れてもいけるんじゃないかな?と思いました。結果、この判断は大正解でした。
- React → 複雑なビューの組み立てをコードで書ける。
- Redux → 状態管理をあまり考えなくてよくなる。全体アーキテクチャもレールに乗れる。
- Typescript → 静的型付けで開発効率が大幅に向上。安心してリファクタリングできる。
実際、この組み合わせで開発をおこなうようになってから、開発しやすく、メンテも楽な状態を保つことができるようになったと思います。(React/Reduxの部分はVue/Vuexなどでも問題ないと思いますが、今回はReact/Reduxを使いました)
Electronについて
ElectronはWebの技術でデスクトップアプリが作成できるツールです。Electronに関しては 公式ドキュメントがすごく充実しています。サンプルコードも多く、開発する上で困ることはあまりありませんでした。
ただ、ElectronはChrominumに基本的に依存しているため、開発中にElectronのバージョンアップに伴うバグが何点か発生しました。発見してものはGitHub上のElectronのプロジェクトにIssueとして登録しました。登録する際はElectronのIssueのポリシーに従い、
- OS
- Electronのバージョン
- 期待する動作
- 実際の動作
- 再現できるコードと再現手順
- 不具合を説明するためのスクリーンショットや動画
あたりをきちんと用意して登録しました。クリティカルなバグもいくつかあり、それらが修正されないとBiscuitがリリースできないため、丁寧ににIssueを登録しました。
中にはElectronの開発者の方の勘違いで、他のIssueとマージされて修正されないバグなどっもありましたが、適時コメントして再オープンしてもらって修正していただきました。このあたりはOSSといっても通常の開発と同じで「コミュニケーション重要」だと思います。
使用したElectron関連のライブラリ
Electron本体と関連する以下のライブラリを使いました。
"dependencies": { ... "about-window": "^1.13.0", // Aboutダイアログ "electron-context-menu": "^0.12.1", // コンテキストメニュー作成 "electron-dl": "^1.14.0", // ファイルダウンロードのヘルパ "electron-find": "^1.0.5", // ブラウザ内でのキーワード検索 "electron-is-dev": "^1.1.0", // 開発モード判定 "electron-log": "^3.0.5", // ログ "electron-squirrel-startup": "^1.0.0", // Windowsでアプリのデスクトップショートカットを作成 "electron-updater": "^4.0.6", // 自動更新 "electron-window-state": "^5.0.3", // Windowのサイズなどを保存 ... }, "devDependencies": { ... "electron": "^6.0.0-beta.10", // Elecyron本体 "electron-builder": "^20.44.4", // パッケージング "electron-notarize": "^0.1.1", // Macのアプリ認可自動化 "electron-reloader": "^0.3.0", // 開発時のオートリロード ... }それぞれのライブラリについては次回書きます。
- 投稿日:2019-06-25T08:58:11+09:00
React.js 学習メモ 第8回
最近Reactの勉強を始めたので、ノート代わりにまとめていきます。
主に自分の学習の流れを振り返りで残す形なので色々、省いてます。
Webエンジニアの諸先輩方からアドバイスやご指摘を頂けたらありがたいです!importしている理由
import は別ファイルに切り出した JavaScript (module) から変数、関数、クラス等を読み込むための宣言!
変数、関数、クラス等を、別ファイルに切り出し、それを読みこむために import を使う。
そのようなモジュールを読み込むためにimportを利用します。PHPであればrequireという構文があります。
外部で利用したいクラスに『export』を付けることで『import』が可能となります。
JavaScript におけるモジュールとは、別ファイルに切り分けられた変数、関数、クラス等のこと。これを用いるために import / export を使う。
読み込む側では、import {名前} from 'ファイル名' とする。
//importで外部クラスを読み込む際のコード import {'module neme'} from 'path to module'exportしている理由
外部ファイルのクラスの読み込み
アプリケーションが大きくなるとモジュール毎に機能を管理していく必要があります。
出力する側では export をしておく。exportの方法は2種類
export class Member {} ・・・名前付きexport
出力する側で変数、関数、クラスの前に export をつける。
この場合のファイル名は、Hello のように、拡張子をつけなくていい。export class Hello extends React.Component { render() { return <div>Hello</div>; } }export defualt class {}・・・デフォルトのexport
export default したものに関しては、import するときに {} を使わない。
1 ファイル内で、1 export default だけしかできない。(通常の export は複数できる)//名前付きexportの場合 import { Hello } from '../' //デフォルトのexportの場合 import Hello from '../'そのため、1ファイルに1コンポーネントだけを作る場合には、default を使う場合がスタンダード
export default する際の書き方
// class の定義をすると同時に // export default する書き方 export default class Hello extends React.Component { render() { return <div>Hello</div>; } }// 一旦 class の定義をしてから class Hello extends React.Component { render() { return <div>Hello</div>; } } // 定義した class を export default するやり方 export default Hello;振り返り
今回は、import,exportについてまとめました。export defaultと名前付きのexportがどのような物であるのかを明確にできたのは初めよく分からない点だったので良かったです。