JavaScript,React

こんにちは、しきゆらです。

最近、怖いと思っていたライブラリやフレームワークは、使ってみると大したことないということに気づき始めました。

Reactさんもその一つです。

基本的なReactの環境構築や使い方をまとめようと思っていますが、今回はちょっとしたメモです。

 

環境

Webpack、Babelを使ってES6をトランスパイルするという状況です。

 

Uncaught TypeError: this.setState is not a function

Reactでstateを変更するときにお世話になる関数であるsetState。

この間、stateを変更すべくsetStateを実行していたら「Uncaught TypeError: this.setState is not a function」とエラーが・・・。

 

コードはこんな感じでした。

import SubComponent from './SubComponent';

class MainComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: props.data,
    }
  }

  updateState(data) {
    this.setState({
      data,
    })
  }

  render(){
    return(
      <SubComponent
        updateState={this.updateState}
      />
    );
  }
}

Mainの方のデータをSubから更新しようとしています。

このとき、上記のようなエラーが起こりました。

 

原因と対策

原因は「this.updateState」のthisがundefinedになることが問題のようです。

対策としては、classで定義する場合constructor内でbindしないと行けないようです。

constructor(){
  super(props); 
  this.state = { data: props.data }

  this.updateState = this.updateState.bind(this); // <= これが重要
}

これでエラーが出ずに更新できるはずです。

わかってしまえば案外簡単ですが、そうでないと無駄に時間がかかってしまいますよね。

 

今回はここまで。

おわり

JavaScript

こんにちは、しきゆらです。

今回は、JSのソート時に特定の要素だけを前/後ろにソートする方法をメモしておきます。

 

・・・お前は何を言っているんだ?

と思われるかもしれませんが、たとえば以下のようにしたい、というのが今回の話。

array = [1,2,3,4,5];
//↓
array.sort() //=> [3,4,5,1,2]

特定の条件に合ったものだけを配列の前/後ろに回してほしいということです。

普通であればfilterとかで分けた後にconcatするのかもしれませんが、

今回はソートだけでなんとかしてみよう、という内容です。

 

JavaScript,React

こんにちは、しきゆらです。

前々回から、Raspiを使ったダッシュボードを作ろうとしています。

 

今回は、クライアントサイドの方で使いたいと思っているReactさんと戯れていこうと思います。

環境構築から、簡単な触り方までを見ていきます。

JavaScript,Mac,環境構築

こんにちは、しきゆらです。

前回、Raspiを使ってダッシュボードのようなものを作りたいということで準備をしていました。

 

そこからかなり間が空いてしまいました。

さっくりと作ろうとしている環境をメモしつつゆっくり進めていこうと思います。

ということで、今回は開発のための環境づくりとしてフロントエンドでよく使われるWebpackを使って見ようと思います。

 

JavaScript

こんにちは、しきゆらです。

今回は、DOMの変化により発火するイベントを知ったので、使い方をメモしておきます。

 

やりたいこと

DOMの数を数えて、数を表示したい。

というのも、最近のライブラリとかならば出来るんだろうけど素のJSでなんとかできないのか、と思って調べてみるとうっかりありました。

その名も、Mutation events!!

Mutation events – ウェブデベロッパーガイド | MDN

しかし、どうもこれは推奨されておらず代わりに使うものを教えてくれていますね。

 

MutationObserver

今回の本題。

これをつかうと、DOMの変更を検知して特定の関数を実行する事ができます。

といっても、基本的なものはMDNさんに使い方があるのでそっちもどうぞ。

MutationObserver – Web API インターフェイス | MDN

 

使い方

基本的には、newでインスタンスを作るだけですね。

// 監視するObserverを作る
let mutation = new MutationObserver(function(){
  console.log("dom change!!");
});
// 監視対象
let target = document.getElementById("hoge");
// 監視するものを指定
let config = {
  children: true,
  subtree: true,
};

// 監視開始
mutation.observer(target, config);

これにより、監視対象に変化があればnewした時に渡したイベントを実行してくれます。

 

変化の監視というのは、属性・文言・子要素等指定ができます。

必要なところを監視できますよ。

[table id=9 /]

 

基本的に、これらを連想配列で渡してあげればいけます。

childList、attribute、characterDataにはtrue/falseを指定するだけ。

簡単ですね。

 

これで、監視対象に変化があれば特定の関数を実行できるようになりました。

Reactさんの真似事が出来るかもしれませんね。

 

今回は、ここまで。

おわり

Electron,HTML/CSS,JavaScript,プログラミング

こんにちは、しきゆらです。

今回は、ElectronでHello Worldを作って遊びたいと思います。

 

前回Electronのことを書いてからすでに半年以上経っていますね。

どうしても、環境構築するだけで満足してしまう部分があります・・・。

環境構築が一番楽しいと思うのですがどうでしょうか。

 

さて、では作っていきます。

JavaScript,プログラミング

こんにちは、しきゆらです。

今回は、よくお世話になるであろうsetIntervalの関数に引数を渡す方法を知ったのでメモしておきます。

 

 

といっても、リファレンスをよく読めば書いてありました。

WindowOrWorkerGlobalScope.setTimeout() – MDN

https://developer.mozilla.org/ja/docs/Web/API/WindowTimers/setTimeout

 

MDNさんによると、setIntervalの引数は「関数オブジェクト」、「遅延させる時間」の2つだけではないようです。

ver timeoutID = scope.setTimeout(function[, delay, param1, param2,...]);

1つめのものですね。

3つ目以降の引数には、関数オブジェクトの引数として渡すものを書けばいいようです。

function hoge(arg1, arg2){
  console.log(arg1, arg2);
}

setInterval(hoge, delay, "hoge", "fuga");

上記のようにすれば、delayミリ秒ごとにconsoleにはhoge, fugaの2つが表示されるはずです。

 

これは知りませんでした。

パっと見ただけでは何をやっているのかわかりませんけど、必要な時はこれで乗り切れそうですね。

 

わかりやすさで言えば、無名関数を作って上げたほうが読みやすいかもしれません。

function hoge(args1){
    console.log(args1);
}

setInterval(function(){
    hoge("hoge");
}, 1000);

 

 

どちらにしても、こうすればsetIntervalの関数に引数を渡せるようです。

知らないことがいっぱいありますね。

 

今回はこのへんで。

おわり。

JavaScript,Ruby,プログラミング

こんにちは、しきゆらです。

今回は、やんごとなき理由により日付を表す文字列をサーバ側からもらい、JSで処理するような状況で困った私が、その時解決した方法をメモしておきます。

 

少しだけ状況を説明すると、

サーバ側ではRubyさんを使って日付を文字列にしてDBへ入れています。

(この段階でSQLのtimestampとか使えばいいのに、と思いうツッコミはなしで)

その日付文字列をJSでパースしてあれこれ処理するようなプログラムを書いていました。

例えば、前回のログイン時間との時間差とか。

 

ここで、問題が起こります。

Rubyで「Time.now」として取得できる日付を表す文字列は、

  • 2017-10-20 23:32:04 +0900

JSで「Date.parse()」で理解できる日付文字列は、

  • Fri Oct 20 2017 23:32:04 GMT+0900

 

これでは、JSは日付を理解できません!

ここからが本題です。

 

JSは日付をパースしたりするとき、IETDF標準日付構文としてパースするようです。

時刻を表す文字列を与えると、parse() は time 値を返します。これは、"Mon, 25 Dec 1995 13:30:00 GMT" のような RFC2822 / IETF 標準の日付構文 (RFC2822 Section 3.3) を受け入れます。

Date.parse() – JavaScript | MDN

JSのDate()で返ってくる文字列は「Fri Oct 06 2017 23:49:19 GMT+0900 (JST)」のような形です。

パースするときも、この文字列形式だと思ってやるようなので、

YYYY-MM-DD HH:MM:SS +0900のような文字列は受け付けてくれません。

※Chrome系のブラウザでは受け付けてくれるようです。

 

何かやんごとなき状況により、「YYYY-MM-DD HH:MM:SS +0900」のような文字列を扱わざるを得ないような場合があるかもしれません。

そこで、サーバ側でJSで理解できる形式に変換してみましょう。

もちろん、Rubyさんでやってみます。

他の言語でも、多分同じような関数があるはずなのでいけるはずです。

time = Time.now
#=> 2017-10-06 23:53:45 +0900
time.strftime("%a %b %d %Y %T GMT%z (%Z)")
#=> "Fri Oct 06 2017 23:53:45 GMT+0900 (JST)"

重要なのは3行目のstrftime。

この書き方で、JSが理解できる日付を表す文字列にできます。

 

日本決め打ちですが、とりあえずこれでJSさんもRubyさんも、この日付をきちんと理解してくれます。
JSさんのDate型には罠が多くて面倒ですね。
早く同じ挙動になってくれ・・・と思う今日このごろ。

とりあえず、Chrome系、Firefox、Safariできちんと読み込めたので大丈夫だと思います。

 

今回はここまで。

おわり。

JavaScript,プログラミング

こんにちは、しきゆらです。

今日は、JavaScriptでフォームのデータを簡単に取得したり、XMLHttpRequestなどで送信しやすいFormDataオブジェクトに触れたら便利だったので、メモしておきます。

 

formタグのデータをJSで取得し、それに追加して他のデータを送りたい場合などはよくあると思います。

そんな時は、formの中にhiddenでinput要素を配置するとか、方法はいくつかあると思います。

でも、HTML的にはhiddenの要素は意味がないので、データの扱いはJSだけで完結していたいですよね。(個人的な意見です)

 

そこで使えるのがFormDataというもの。

formタグの中身をそのままkey, valueの組み合わせで表現できる魔法のようなオブジェクトです。

参考:FormData – MDN

簡単な使い方をまとめておきます。

 

JavaScript,プログラミング

こんにちは、しきゆらです。

今回は、NodeListなどのArrayっぽいオブジェクトの扱いについてメモしておきます。

 

DOMを扱うとよく現れるNodeListなど、Arrayっぽくあるものがちょくちょくあります。

Arrayに似ているけど、concatとかArrayの便利メソッドは使えません。

このArrayっぽいものをArrayに直す方法です。

// NodeList
var divs = document.querySelectorAll("div");
// HTMLCollection
var ps = document.getElementsByTagName("p");

// Arrayに変換
divs = [].slice.call(divs);
ps = [].slice.call(ps);

[].sliceはどのブラウザでも動くようです。

IEを無視すれば、以下のものでも良さそうです。

divs = Array.from(divs); 
ps = Array.from(ps);

 

今回のことは、ほとんどMDNに書いてあることでした。

意外と見えていないんだなぁと。

以下のあたりを見ました。

参考

 

 

今回はここまで。

おわり