- 投稿日:2020-01-22T18:39:22+09:00
TypeScriptでstyle-componentsの"as" propにNextLinkコンポーネントを渡したい時
実装したかったこと
labelコンポーネントにおいて、リンク付きにしたい箇所とリンクなしにしたい箇所があったので、
<a>
に置き換えるものと置き換えないで<label>
のままにしておくものを作りたい。やったこと
as prop
を使用し解決しようとしました。export const CategoryLink: React.FunctionComponent<LinkProps> = ({ title = 'メンヘラ', href, }) => ( <CategoryLabel as={Link} href={href}> {title} </CategoryLabel> );これでいけると思いました。怒られました
Types of property 'as' are incompatible. Type 'typeof Link' is not assignable to type 'string | UrlObject | undefined'. Type 'typeof Link' has no properties in common with type 'UrlObject'.これは、参照できる
as
ではないよ。Urlobjectが未定義だよ。
types of LinkにはUrlObjectと共通のプロパティがないよ。と言われました。
とりあえずエラーをもとに、
styled-componet ts as link
のワードでググりました。すると同じようなことで悩んでるZeit公式のissueにぶつかりました。
こうしたらいけると公式が言うからいけるのでしょう!
やってみます。
export const CategoryLink: React.FunctionComponent<LinkProps> = ({ title = 'メンヘラ', href, }) => ( <Link href={href} passHref> <CategoryLabel as="a"> {title} </CategoryLabel> </Link> );できました!!!!!!!!
(レイアウトは今作り段階なのでゴミです許してください)
何がダメだったのか?
こちらはNext.jsの公式 Routingのところから抜粋したものです。
Next.jsのRoutingで設定してるas
とstyled-componentで設定しようとしたas
が被っていた。
Next.jsのRoutingのas
をTypeScript側は、参照しようとしるのに、私がstyled-componentのas
を提示したため、types of LinkにはUrlObjectと共通のプロパティがないよ
と言うエラーになったと言うわけです。ちなみに
現時点でわかった
as
が受け取れるものは以下です。
- HTMLのネイティブタグを文字列で渡す
- styled-componentで作ったコンポーネントタグを
{component}
で渡すなので下のコードも通ります。
export default CategoryLabel; const Foo = styled.h1` `; export const CategoryLink: React.FunctionComponent<LinkProps> = ({ title = 'メンヘラ', href, }) => ( <CategoryLabel as={Foo}> {title} </CategoryLabel> );以上です!
メンヘラなので、何か助言あれば優しい言葉でお願いします。
- 投稿日:2020-01-22T18:39:22+09:00
TypeScriptでstyled-componentsの"as" propにNextLinkコンポーネントを渡したい時
実装したかったこと
<label>
要素において、リンク付きにしたい箇所とリンクなしにしたい箇所があったため、以下のように2通りのケースに対応できるようにしたい。
<label>
をベースにスタイルを定義する。<label>
を<a>
に置き換えて、スタイルは全く同じものを使用する。やったこと
"as"
prop を使用し解決しようとしました。export const CategoryLink: React.FunctionComponent<LinkProps> = ({ title = 'メンヘラ', href, }) => ( <CategoryLabel as={Link} href={href}> {title} </CategoryLabel> );これでいけると思いました。怒られました
Types of property 'as' are incompatible. Type 'typeof Link' is not assignable to type 'string | UrlObject | undefined'. Type 'typeof Link' has no properties in common with type 'UrlObject'.これは、
"as"
の型が間違ってるよ。Link
の型は ("as"
で要求されている)string | UrlObject | undefined
のどれにも該当しないよ。Link
の型は (唯一オブジェクトとして検査する価値のある)UrlObject
のプロパティと構成が全く違うよ。と言われました。とりあえずエラーをもとに、
styled-componet ts as link
のワードでググりました。すると同じようなことで悩んでるZeit公式のissueにぶつかりました。こうしたらいけると公式が言うからいけるのでしょう!やってみます。
export const CategoryLink: React.FunctionComponent<LinkProps> = ({ title = 'メンヘラ', href, }) => ( <Link href={href} passHref> <CategoryLabel as="a"> {title} </CategoryLabel> </Link> );できました!!!!!!!!
(レイアウトは今作り段階なのでゴミです許してください)
何がダメだったのか?
こちらはNext.jsの公式 Routingのところから抜粋したものです。
- Next.jsのRoutingで設定してる
as
とstyled-componentで設定しようとしたas
が被っていた。- Next.jsのRoutingの
as
をTypeScript側は参照しようとしているのに、私がstyled-componentのas
を提示した。このため
Link
の型は (唯一オブジェクトとして検査する価値のある)UrlObject
のプロパティと構成が全く違うよ。と言うエラーになったと言うわけです。
ちなみに
現時点でわかった
as
が受け取れるものは以下です。
- HTMLのネイティブ要素名(文字列)
- styled-componentで作ったコンポーネント(オブジェクト)
なので下のコードも通ります。
export default CategoryLabel; const Foo = styled.h1` `; export const CategoryLink: React.FunctionComponent<LinkProps> = ({ title = 'メンヘラ', href, }) => ( <CategoryLabel as={Foo}> {title} </CategoryLabel> );以上です!
メンヘラなので、何か助言あれば優しい言葉でお願いします。
- 投稿日:2020-01-22T18:22:44+09:00
React.Componentのメンバ変数は、再レンダー時に更新されるとは限らない!
Reactで
setState()
しても値が更新されなくてハマったので、記事化します。更新すべき値をメンバ変数に格納した場合
ボタンを押すと値が+1されるアプリケーションを作ります。
以下は間違ったコードです。
Appでカウンターの値を管理し、Counterはその値とカウントボタンを表示します。app.jsimport React from 'react' import ReactDOM from 'react-dom' import Counter from './counter' class App extends React.Component { constructor(props) { super(props) this.state = {count: 0} this.increment = this.increment.bind(this) } increment() { this.setState( (state) => {return {count: state.count + 1}} ) } render() { return ( <Counter count={this.state.count} onClick={this.increment} /> ) } } let app = document.getElementById('app') ReactDOM.render(<App />, app)counter.jsimport React from 'react' class Counter extends React.Component { constructor(props) { super(props) this.count = this.props.count } render() { // 以下の`this.count`は、新しいpropsを反映しない! return ( <div> <p>{this.count}</p> <button onClick={this.props.onClick}>カウント</button> </div> ) } } export default Counterこのコードを実行し、ボタンをクリックしても、カウンターの値は増加しないと思います。
レンダーごとに更新する値は、メンバ変数に保存しない
値が更新されない原因は、表示する値が
this.count
になっていることです。
counter.jsを以下のように修正すれば、ちゃんとカウント値が増加します。counter.jsimport React from 'react' class Counter extends React.Component { constructor(props) { super(props) } render() { return ( <div> <p>{this.props.count}</p> <button onClick={this.props.onClick}>カウント</button> </div> ) } } export default Counter今回は、
this.props.count
を表示するだけなので、わざわざメンバ変数に格納することはありませんが、表示させるべき値が複雑になる場合、render
メソッドの戻り値に直接式を書かずに、結果を変数に格納したい場合があります。そういう場合は、たとえば関数にすると良いと思います。counter.jsclass Counter extends React.Component { constructor(props) { super(props) } render() { let count = this._getCount() return ( <div> <p>{count}</p> <button onClick={this.props.onClick}>カウント</button> </div> ) } _getCount() { let count; // すごく複雑な処理 return count } }以上です。
- 投稿日:2020-01-22T15:13:20+09:00
React勉強の備忘録
React HooksのuseState
React HooksのuseStateがどういう原理で実現されてるのかさっぱりわからなかったので調べた
https://sbfl.net/blog/2019/02/09/react-hooks-usestate/
- 投稿日:2020-01-22T13:16:42+09:00
base64形式にして画像を表示できるようにする React
初めてbase64を使ったのでメモ
base64とは
この記事を読むとわかる
base64ってなんぞ??理解のために実装してみたbase64に変換してくれるサイト
実際にbase64化されたURLをブラウザで検索して、画像が表示されてたらbase64化できてる
実装方法
logo.jsexport const logo ="base64形式のURL"App.jsimport logo from './logo' (コード省略) <img src={logo} alt={画像が表示されない時に代わりに表示したい文字} />画像を export して 読み込みたいところでimportして使える!
- 投稿日:2020-01-22T05:51:58+09:00
[React]どこからか受け取ったHTMLの文字列を、HTML要素として画面に表示しつつ、特定ワードでハイライトしたい
背景
開発中のシステムで、データベースにHTMLが入っているカラムがあり、それをAPIで取ってきて、Reactで表示するという構成の画面があります。
その画面にはHTML内の文字列を検索できる機能があり、「検索ワードをハイライトして表示できないか?」という相談を受けたので、実装しました。(Google検索だと、ハイライトではなく太字になっていますが、やりたいことはこんな感じです)
ただ文字列をハイライトするのはかんたんですが、HTMLとしてレンダリングしつつというところで少し悩んだので記事にしました。
できたもの
だいたいこのような感じです。
HTMLに対して、スペース区切りで文字を入力したら、入力された文字とマッチする箇所をハイライトします。
codesandboxに上げました。
ポイント
文字をハイライトさせるのには、react-highlight-wordsというパッケージが便利だったので使っています。
処理の流れは、
- (HTMLのstring)HTMLをstateから受け取る
- (React elementでstringをラップ)ハイライトしてくれるコンポーネントに突っ込む
- (HTMLのstring)
react-dom/server
でサーバで一旦レンダリングする- (HTMLのstring)正規表現でHTMLタグをアンエスケープする
- (React Element)dangerouslySetInnerHTMLというHTMLのstringをReactでHTML要素として表示できるプロパティに入れる
という感じです。
もしかしたらもっといいやり方があるかもですね。HTMLタグのアンエスケープはこれでできます。
const unescapeHtml = string => { const patterns = { "<": "<", ">": ">", "&": "&", """: '"', "'": "'", "`": "`" }; const escapedString = string.replace( /&(lt|gt|amp|quot|#x27|#x60);/g, match => patterns[match] ); return escapedString; };注意
HTML内部のリンクとマッチするワードが入力されたら、HTMLがこわれます。
必要ならエスケープすることになります。
また、もととなるデータが、ユーザーが自由に入れることができるものである場合は、XSS対策などセキュリティ対策が必要です。
- 投稿日:2020-01-22T04:10:24+09:00
Reactで行数可変なtextareaを作った話
TL;DR
中身に応じて高さが変わるtextareaが出来た
コピペ、複数行まとめて削除しても大丈夫軽く検索しても出てこなかったので
似たようなことをしたくなった人や未来の自分のために書いてみました環境
react:15.6.2
redux-form:6.8.0
lodash.isempty:4.4.0正直reactだけでもOKなはず
廃止されるライフサイクルメソッドなども使っていないので最新版のreactでも動くと思います他2つは細かいところ書くのが面倒なので使ってます
無くても本質には関係ないので大丈夫ですchromeとIEで動作確認済み(バージョンはわからないですが2020/01付近です)
参考
実装
細かいところはフィーリングで読んでください
index.jsimport React from 'react'; import { Field, reduxForm } from 'redux-form'; import TextArea from './textArea'; function index() { return ( <div> <Field name="TextArea" component={TextArea} rows={2} /> </div> ) } export default reduxForm({ form: 'form' })(index);textArea.jsimport React, { Component } from 'react'; import isEmpty from 'lodash.isempty'; class TextArea extends Component { constructor(props) { super(props); this.textArea = null; } shouldComponentUpdate(nextProps) { if (this.props.input.value !== nextProps.input.value) { if (isEmpty(nextProps.input.value)) { this.textArea.setAttribute('rows', this.props.rows); } else { this.textArea.setAttribute('rows', this.props.rows); while (this.textArea.scrollHeight > this.textArea.offsetHeight) { const tempRows = Number(this.textArea.getAttribute('rows')); this.textArea.setAttribute('rows', tempRows + 1); } } } return true; } render() { return ( <textarea ref={c => { this.textArea = c; }} style={{ resize: 'none' }} name={this.props.input.name} onChange={e => this.props.input.onChange(e.target.value, this.props.input.name)} rows={this.props.rows} /> ); } }解説
参考にしたコードと似たようなことをしています
以下の部分が全てですshouldComponentUpdate(nextProps) { // textareaの内容が変更された時のみ操作 if (this.props.input.value !== nextProps.input.value) { if (isEmpty(nextProps.input.value)) { // 内容が空なら初期値の行数に戻すだけ this.textArea.setAttribute('rows', this.props.rows); } else { this.textArea.setAttribute('rows', this.props.rows); // 内容が有るならスクロールせずに表示できる高さになるまで初期値から1行ずつ増やす while (this.textArea.scrollHeight > this.textArea.offsetHeight) { const tempRows = Number(this.textArea.getAttribute('rows')); this.textArea.setAttribute('rows', tempRows + 1); } } } return true; }注意点
高さにmax-heightなどで上限を定めたい時は
直接textareaにmax-heightを書かないでください高さの計算とぶつかるのか無限ループになってブラウザが固まります
高さを決めたい場合は適当にラップしてそちらに色々設定してください※今回で言うと、index.jsのdivに{max-height: 100px, overflow-y: scroll}みたいにすれば
100pxより入力欄が高くなったらスクロールになるよう切り替えられますまとめ
shouldComponentUpdateでこういうことして良いのかはわかりませんがとりあえず動いてるのでヨシとします
横方向(cols)にも同じ方法で拡縮できるのではないかと思いますがそこまでは試してないです
- 投稿日:2020-01-22T00:28:30+09:00
【React】Next.jsをfirebaseにデプロイする方法
package.jsonを修正
"start"に「-p $PORT"」を追記かつ、"export"を追加
"scripts": { "dev": "next", "build": "next build", "start": "next start -p $PORT", "export": "next export" },build & export
以下コマンドを叩いて、ビルドする
npm run buildそのあと、エクスポートする
npm run exportbuild&exportに成功するとoutフォルダに、静的ファイルが吐き出される
firebaseのデプロイ準備
まずは、以下コマンドを叩く
firebase init各質問に答えていき、以下の質問の際に「out」を入力する
? What do you want to use as your public directory? outfirebase.jsonに正しい内容が記載されていることを確認して、デプロイ実行
firebase deploy以上!
- 投稿日:2020-01-22T00:10:37+09:00
デザイナがReactを始める前に押さえておきたいJavascriptの基本③(クラス編)
はじめに
テーブルレイアウトからcssスタイリングへの過渡期だった頃、私はWebデザイナーを目指し始めました。
それから◯年あまりの間、ビジュアルを作ったり、HTML・CSS・jQuery(コピペ多め)でのマークアップをやってまいりました。そんな中、ここ最近急速にフロントエンド界隈の難易度が上がり、今までデザイナが担当していた分野のフロントエンドコーディングにおいても、より専門性の高いJSコーディングスキル、Reactなどの知識が求められるようになりました。
自身がReactを学ぶ上で色々とつまずき、心折れそうになった理由は、Javascriptの配列・オブジェクト・クラスをきちんと理解しないまま始めてしまったから。
この経験に基づき、デザイナがReactを始める前に最低限押さえておくべきJavascriptの基本(個人的見解)について、3回(予定)に分けて書きます。
- JavaScriptの基本①(配列編) 読んでね
- Javascriptの基本②(オブジェクト編) 読んでね
- Javascriptの基本③(クラス編) 今ここ
クラス構文
オブジェクトをテンプレート化できるのがクラス構文です。
色々な関数をひとまとめにして使い回せたり、他のクラスに内容を引き継ぐことができるので、よりメンテナンス性の高いコードを書くことができます。(前提知識としてオブジェクトの基本への理解が必要です。)
クラス構文に書き換えてテンプレートを作る
まずはJavascriptの基本②(オブジェクト編)の復習も兼ねて、複数オブジェクトの配列とメソッドを使って多角形の内角の和を求めるコードを作成し、そこからクラス構文を使ったテンプレートを作っていきます。
図形 含まれる三角形の数 内角の和 3角形 1 180° 4角形 2 360° 5角形 3 540° 6角形 4 720° const insideAngleSums = [ { n: 3, //3角形 getAngleSum(){console.log(`${this.n}角形の内角の和は${180 * (this.n - 2)}°`)} }, { n: 4, //4角形 getAngleSum(){console.log(`${this.n}角形の内角の和は${180 * (this.n - 2)}°`)} }, { n: 5, //5角形 getAngleSum(){console.log(`${this.n}角形の内角の和は${180 * (this.n - 2)}°`)} }, { n: 6, //6角形 getAngleSum(){console.log(`${this.n}角形の内角の和は${180 * (this.n - 2)}°`)} } ]insideAngleSums[0].getAngleSum() //3角形の内角の和は180° insideAngleSums[1].getAngleSum() //4角形の内角の和は360° insideAngleSums[2].getAngleSum() //5角形の内角の和は540° insideAngleSums[3].getAngleSum() //6角形の内角の和は720°
図形 含まれる三角形の数 内角の和 n角形 n-2 180°* (n-2) n角形の内角の和の公式は
180 * (n - 2)
クラス構文を使って、この公式をテンプレート化してみます。
コンストラクタはインスタンス生成時に呼び出される関数です。class InsideAngleSum { //classの最初の I は大文字 constructor(n){ //constructor()で初期化し、nの値には引数を渡してセット this.n = n //このクラスから作られるインスタンスはthisで表現できる } getAngleSum(){console.log(`${this.n}角形の内角の和は${180 * (this.n - 2)}°`)} }const insideAngleSums = [ //newを使ってインスタンスを作る new InsideAngleSum(3), new InsideAngleSum(4), new InsideAngleSum(5), new InsideAngleSum(6) ] insideAngleSums.forEach(insideAngleSum => insideAngleSum.getAngleSum()) //3角形の内角の和は180° //4角形の内角の和は360° //5角形の内角の和は540° //6角形の内角の和は720°テンプレートする前と同じ結果になりました。
ちなみに100角形の内積の和を求めてみると。。new InsideAngleSum(100).getAngleSum() // 100角形の内角の和は17640°クラスの継承
さらにclass構文は、内容を他のclass構文に引き継げるので、もともと書かれている構文を変更せずに内容の追加などを行なうことができます。
まず三角形の面積を求める公式をクラスにしてみます。
底辺 * 高さ / 2
から、class Triangle { constructor(width, height){ this.width = width this.height = height } area(){console.log(`底辺${this.width}cm 高さ${this.height}cm の三角形の面積は、${this.width * this.height / 2}㎠ です。`)} }n角形の内角の和の公式を親クラス、三角形の面積の公式を子クラスとして継承させてみます。
(クラスの仕組みを説明するという目的達成のために、無理やりなコードになってしまってるかも)class InsideAngleSum { //親クラス constructor(n){ this.n = n } getAngleSum(){console.log(`${this.n}角形の内角の和は${180 * (this.n - 2)}°`)} //staticで始まる静的メソッドはインスタンスを介さずに、直接クラスから呼び出せる。(インスタンスを介さないので、thisは使えない) static outsideAngleSum(){console.log('多角形は何角形でも外角の和は360°')} } class Triangle extends InsideAngleSum { //extends InsideAngleSumでInsideAngleSumクラスに書かれたコードが、そのまま Triangle クラスに引き継がれる constructor(n, width, height){ //子クラスの constructor()で this を使うには constructor()の最初に super()と記述。親クラスの constructor()が呼ばれ、親クラスで引数も渡しているのでここでも渡す。 super(n) this.width = width this.height = height } polygon(){console.log(`${this.n}角形!!`)} area(){ console.log(`底辺${this.width}cm 高さ${this.height}cm の三角形の面積は、${this.width * this.height / 2}㎠ です。`) super.getAngleSum() //親クラスのメソッドを呼ぶには、super をつける。 this.polygon() // 子クラスのthisは定義されたクラス自身のメソッドを指す InsideAngleSum.outsideAngleSum() //静的メソッドはクラスから直接呼び出せる。 } } const info = new Triangle(12, 5, 8) console.log(info.area()) //底辺5cm 高さ8cm の三角形の面積は、20㎠ です。 //12角形の内角の和は1800° //12角形!! //多角形は何角形でも外角の和は360°シンプルにまとめられました
最後に
道半ばですが、分からないことがあっても諦めずに少しずつすすめると、小さな成長を感じる瞬間があります。
そんな素敵な瞬間を楽しみながら頑張ろうと思っております
フロントエンドスキルを武器にしたいWebデザイナーのみなさん、一緒にがんばりましょう!次回からはReact入門編の記事をシリーズで書いてみたいと思います。
参考にさせていただいたサイト
- 投稿日:2020-01-22T00:10:37+09:00
デザイナがReactを始める前に押さえておきたいJavaScriptの基本③(クラス編)
はじめに
テーブルレイアウトからcssスタイリングへの過渡期だった頃、私はWebデザイナーを目指し始めました。
それから◯年あまりの間、ビジュアルを作ったり、HTML・CSS・jQuery(コピペ多め)でのマークアップをやってまいりました。そんな中、ここ最近急速にフロントエンド界隈の難易度が上がり、今までデザイナが担当していた分野のフロントエンドコーディングにおいても、より専門性の高いJSコーディングスキル、Reactなどの知識が求められるようになりました。
自身がReactを学ぶ上で色々とつまずき、心折れそうになった理由は、JavaScriptの配列・オブジェクト・クラスをきちんと理解しないまま始めてしまったから。
この経験に基づき、デザイナがReactを始める前に最低限押さえておくべきJavaScriptの基本(個人的見解)について、3回(予定)に分けて書きます。
- JavaScriptの基本①(配列編) 読んでね
- JavaScriptの基本②(オブジェクト編) 読んでね
- JavaScriptの基本③(クラス編) 今ここ
クラス構文
オブジェクトをテンプレート化できるのがクラス構文です。
色々な関数をひとまとめにして使い回せたり、他のクラスに内容を引き継ぐことができるので、よりメンテナンス性の高いコードを書くことができます。(前提知識としてオブジェクトの基本への理解が必要です。)
クラス構文に書き換えてテンプレートを作る
まずはJavaScriptの基本②(オブジェクト編)の復習も兼ねて、複数オブジェクトの配列とメソッドを使って多角形の内角の和を求めるコードを作成し、そこからクラス構文を使ったテンプレートを作っていきます。
図形 含まれる三角形の数 内角の和 3角形 1 180° 4角形 2 360° 5角形 3 540° 6角形 4 720° const insideAngleSums = [ { n: 3, //3角形 getAngleSum(){console.log(`${this.n}角形の内角の和は${180 * (this.n - 2)}°`)} }, { n: 4, //4角形 getAngleSum(){console.log(`${this.n}角形の内角の和は${180 * (this.n - 2)}°`)} }, { n: 5, //5角形 getAngleSum(){console.log(`${this.n}角形の内角の和は${180 * (this.n - 2)}°`)} }, { n: 6, //6角形 getAngleSum(){console.log(`${this.n}角形の内角の和は${180 * (this.n - 2)}°`)} } ]insideAngleSums[0].getAngleSum() //3角形の内角の和は180° insideAngleSums[1].getAngleSum() //4角形の内角の和は360° insideAngleSums[2].getAngleSum() //5角形の内角の和は540° insideAngleSums[3].getAngleSum() //6角形の内角の和は720°
図形 含まれる三角形の数 内角の和 n角形 n-2 180°* (n-2) n角形の内角の和の公式は
180 * (n - 2)
クラス構文を使って、この公式をテンプレート化してみます。
コンストラクタはインスタンス生成時に呼び出される関数です。class InsideAngleSum { //classの最初の I は大文字 constructor(n){ //constructor()で初期化し、nの値には引数を渡してセット this.n = n //このクラスから作られるインスタンスはthisで表現できる } getAngleSum(){console.log(`${this.n}角形の内角の和は${180 * (this.n - 2)}°`)} }const insideAngleSums = [ //newを使ってインスタンスを作る new InsideAngleSum(3), new InsideAngleSum(4), new InsideAngleSum(5), new InsideAngleSum(6) ] insideAngleSums.forEach(insideAngleSum => insideAngleSum.getAngleSum()) //3角形の内角の和は180° //4角形の内角の和は360° //5角形の内角の和は540° //6角形の内角の和は720°テンプレートする前と同じ結果になりました。
ちなみに100角形の内積の和を求めてみると。。new InsideAngleSum(100).getAngleSum() // 100角形の内角の和は17640°クラスの継承
さらにclass構文は、内容を他のclass構文に引き継げるので、もともと書かれている構文を変更せずに内容の追加などを行なうことができます。
まず三角形の面積を求める公式をクラスにしてみます。
底辺 * 高さ / 2
から、class Triangle { constructor(width, height){ this.width = width this.height = height } area(){console.log(`底辺${this.width}cm 高さ${this.height}cm の三角形の面積は、${this.width * this.height / 2}㎠ です。`)} }n角形の内角の和の公式を親クラス、三角形の面積の公式を子クラスとして継承させてみます。
(クラスの仕組みを説明するという目的達成のために、無理やりなコードになってしまってるかも)class InsideAngleSum { //親クラス constructor(n){ this.n = n } getAngleSum(){console.log(`${this.n}角形の内角の和は${180 * (this.n - 2)}°`)} //staticで始まる静的メソッドはインスタンスを介さずに、直接クラスから呼び出せる。(インスタンスを介さないので、thisは使えない) static outsideAngleSum(){console.log('多角形は何角形でも外角の和は360°')} } class Triangle extends InsideAngleSum { //extends InsideAngleSumでInsideAngleSumクラスに書かれたコードが、そのまま Triangle クラスに引き継がれる constructor(n, width, height){ //子クラスの constructor()で this を使うには constructor()の最初に super()と記述。親クラスの constructor()が呼ばれ、親クラスで引数も渡しているのでここでも渡す。 super(n) this.width = width this.height = height } polygon(){console.log(`${this.n}角形!!`)} area(){ console.log(`底辺${this.width}cm 高さ${this.height}cm の三角形の面積は、${this.width * this.height / 2}㎠ です。`) super.getAngleSum() //親クラスのメソッドを呼ぶには、super をつける。 this.polygon() // 子クラスのthisは定義されたクラス自身のメソッドを指す InsideAngleSum.outsideAngleSum() //静的メソッドはクラスから直接呼び出せる。 } } const info = new Triangle(12, 5, 8) console.log(info.area()) //底辺5cm 高さ8cm の三角形の面積は、20㎠ です。 //12角形の内角の和は1800° //12角形!! //多角形は何角形でも外角の和は360°シンプルにまとめられました
最後に
道半ばですが、分からないことがあっても諦めずに少しずつすすめると、小さな成長を感じる瞬間があります。
そんな素敵な瞬間を楽しみながら頑張ろうと思っております
フロントエンドスキルを武器にしたいWebデザイナーのみなさん、一緒にがんばりましょう!次回からはReact入門編の記事をシリーズで書いてみたいと思います。
参考にさせていただいたサイト