ジャンボモナカ

34歳のハゲデブがHTML5ハイブリッドアプリ開発プラットフォームmonacaを始めました。

脱jQuery~JavaScriptに支配されないための真の思考法~ removeClassメソッド

jQueryのremoveClassメソッドをネイティブJavaScript(vanilla JS)で実装する方法について書く。

まずは、removeClassメソッドを使って一つクラス名を設定する方法について。

// jQuery
$('#hoge').removeClass('foo');

// JavaScript
document.querySelector('#hoge').classList.remove('foo');

// jQuery
$('.hoge').removeClass('foo');

// JavaScript
document.querySelectorAll('.hoge').forEach(function(currentValue){
  currentValue.classList.remove('foo');
});

次にremoveClassメソッドを使って複数のクラス名を設定する方法について。

// jQuery
$('#hoge').removeClass('foo bar');

// JavaScript
'foo bar'.split(' ').forEach(function(currentValue){
  document.querySelector('#hoge').classList.remove(currentValue);
});


// jQuery
$('.hoge').removeClass('foo bar');

// JavaScript
document.querySelectorAll('.hoge').forEach(function(currentElement){
  'foo bar'.split(' ').forEach(function(currentValue){
    currentElement.classList.remove(currentValue);
  });
});

removeメソッドはクラス名を複数設定することができるみたいなのだが、IE11が対応していないのでループをまわした書き方にした。

脱jQuery~JavaScriptに支配されないための真の思考法~ addClassメソッド

jQueryのaddClassメソッドをネイティブJavaScript(vanilla JS)で実装する方法について書く。

まずは、addClassメソッドを使って一つクラス名を設定する方法について。

// jQuery
$('#hoge').addClass('foo');

// JavaScript
document.querySelector('#hoge').classList.add('foo');

// jQuery
$('.hoge').addClass('foo');

// JavaScript
document.querySelectorAll('.hoge').forEach(function(currentValue){
  currentValue.classList.add('foo');
});

次にaddClassメソッドを使って複数のクラス名を設定する方法について。

// jQuery
$('#hoge').addClass('foo bar');

// JavaScript
'foo bar'.split(' ').forEach(function(currentValue){
  document.querySelector('#hoge').classList.add(currentValue);
});


// jQuery
$('.hoge').addClass('foo bar');

// JavaScript
document.querySelectorAll('.hoge').forEach(function(currentElement){
  'foo bar'.split(' ').forEach(function(currentValue){
    currentElement.classList.add(currentValue);
  });
});

addメソッドはクラス名を複数設定することができるみたいなのだが、IE11が対応していないのでループをまわした書き方にした。

ReactのsetStateでstateが即時反映されない件

ReactでsetStateを呼び出した直後にその変数を参照しにいこうとすると更新が反映されていないケースがある。

例えば、componentDidMountメソッドでsetStateを呼び出して、stateの更新依頼をかけた後、すぐにcomponentDidMountメソッド内でそのstateを参照する場合、値が反映されていないケース。

class Hoge extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      foo:1
    };
  }

  componentDidMount(){
    this.setState({
      foo:2
    })
    // 下は1となる(本来は2になってほしい)
    console.log(this.state.foo)
  }
  render(){
    return <span>{this.state.foo}</span>
  }
}

ReactDOM.render(
  <Hoge />,
  document.getElementById('bar')
);

renderメソッドで使われるstateの値に関しては更新が完了した後に呼び出されるので正常に動作する。

この件に関しては、Facebookも把握しており、In depth: Why isn’t this.state updated immediately?というリンクがあった。

github.com

では、stateが更新されたタイミングで特定の処理を実行したい場合はどうすればいいのだろうか?

これも公式サイトに書いてあったのだが、componentDidUpdateメソッドを呼び出すか、setStateメソッドでコールバックを呼び出すことで対応できるようだ。 (ってかコールバックぐらいmain conceptsに書いておけよって言いたくなるのは気のせい?)

まずは、componentDidUpdateメソッドを使ったパターン

class Hoge extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      foo:1
    };
  }

  componentDidMount(){
    this.setState({
      foo:2
    })
    
  }

  componentDidUpdate(prevProps, prevState, snapshot){
    // 下は2になる(正常終了)
    console.log(this.state.foo)
  }

  render(){
    return <span>{this.state.foo}</span>
  }
}

ReactDOM.render(
  <Hoge />,
  document.getElementById('bar')
);

次にsetStateのコールバックを使ったパターン

class Hoge extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      foo:1
    };
  }

  componentDidMount(){
    this.setState({
      foo:2
    },()=>{
      // 下は2になる(正常終了)
      console.log(this.state.foo)
    })
    
  }

  render(){
    return <span>{this.state.foo}</span>
  }
}

ReactDOM.render(
  <Hoge />,
  document.getElementById('bar')
);

setStateのコールバックもcomponentDidUpdateメソッドを使ったパターンも正常動作した。

しかし、注意点として、複数メンバーで実装を行なっていた場合、使い方をあわせないと、改修を行う際、プログラムの統一性が測れなくなり、混乱をきたす可能性がある。

今さら人に聞けないReactをIE11に対応する方法

Reactの公式サイトに記載があるのだが、デフォルトではReactはIE9、IE10、IE11には対応していない。 (IE8はどうした(笑))

facebook.github.io

だが、windows7windows8という古いOSを使っているユーザーの場合は、EdgeではなくIE11あたりを使っているはず。

そこで、ReactをIE11対応したいケースもあるわけで、その方法について調べた。

IE11に対応するには、Polyfillと呼ばれる新しいJavaScriptの機能を古いブラウザでも対応させる技術を導入すればいいみたいだ。

具体的には、npmでreact-app-polyfillをインストールする。

npm install react-app-polyfill

プログラムで使う場合は、importでreact-app-polyfill/ie11をインクルードすれば解決する。

import 'react-app-polyfill/ie11';
import * as React from 'react';
import * as ReactDOM from 'react-dom';

確かにIE11のブラウザで確認したらエラーがでなかった。

脱jQuery~JavaScriptに支配されないための真の思考法~ attrメソッド

jQueryのattrメソッドをネイティブJavaScript(vanilla JS)で実装する方法について書く。

まずは、attrメソッドを使って一つ属性を設定する方法について。

// jQuery
$('a').attr('href','https://yahoo.co.jp');


// JavaScript
document.querySelector('a').setAttribute('href','https://yahoo.co.jp');

続いて複数の属性を設定する場合について。

// jQuery
$('img').attr({
  'src': 'https://dummyimage.com/300',
  'alt': 'ダミー画像'
});


// JavaScript
var _img = document.querySelector('img')
_img.setAttribute('src','https://dummyimage.com/300');
_img.setAttribute('alt','ダミー画像');

最後にattrメソッドを使って属性値を取得する方法について書く。

// jQuery
var _href = $('a').attr('href');


// JavaScript
var _href = document.querySelector('a').getAttribute('href');

脱jQuery~JavaScriptに支配されないための真の思考法~ appendメソッド

jQueryのappendメソッドをネイティブJavaScript(vanilla JS)で実装する方法について書く。

// jQuery
$('#hoge').append($('<div></div>'));


// JavaScript
document.querySelector('#hoge').appendChild(document.createElement('div'));