React + styled-components で頻出するES6のびっくり記法を冗長に書き直してみる

React + styled-components で頻出するES6のびっくり記法を冗長に書き直してみる:

書き直したら読みやすくなるわけでは決してありません!


概要

「constとか、テンプレートリテラルくらいはわかるけど・・・」みたいな方にむけて、今更ではありますがES6の理解を深めるため、ReactのよくあるStateless Functional Componentsを書き直してみます。

例としたコンポーネントはこちらです。

button.js
import React from 'react' 
import styled from 'styled-components' 
// ↑今後は省略 
 
export default ({ 
  text = 'Button', 
  primary = false 
}) => ( 
  <Wrapper primary={primary}> 
    {text} 
  </Wrapper> 
) 
 
const Wrapper = styled.button` 
  padding: 10px; 
  ${({ primary }) => primary && ` 
    background-color: #f99; 
    color: #fff; 
  `} 
  font-size: 12px; 
` 


アロー関数の簡潔文体

アロー関数においてブロック{}を利用せずに、単一の式だけを記述した場合、その式が明示的に return される値となります。

var func = x => x * x; // x * x の結果が return される 
簡潔文体を使わずに書き直すとこうなります。

button.js
export default ({ 
  text = 'Button', 
  primary = false 
}) => { // ここ! 
  return ( 
    <Wrapper primary={primary}> 
      {text} 
    </Wrapper> 
  ) 
} 
 
const Wrapper = styled.button` 
  padding: 10px; 
  ${({ primary }) => {  // ここ! 
    return primary && ` 
      background-color: #f99; 
      color: #fff; 
    `} 
  } 
  font-size: 12px; 
` 


デフォルト引数

関数に値が渡されない場合や undefined が渡される場合に、デフォルト値で初期化される形式上の引数を指定できます。

function multiply(a, b = 1) { 
  return a*b; 
} 
 
multiply(5); // 5 
大変便利ですが、書き直します。

button.js
export default ({ 
  text, // ここ! 
  primary 
}) => { 
  text = typeof text !== 'undefined' ? text : 'Button' // ここ! 
  primary = typeof primary !== 'undefined' ? primary : false 
  return ( 
    <Wrapper primary={primary}> 
      {text} 
    </Wrapper> 
  ) 
} 
 
const Wrapper = styled.button` 
  padding: 10px; 
  ${({ primary }) => { 
    return primary && ` 
      background-color: #f99; 
      color: #fff; 
    `} 
  } 
  font-size: 12px; 
` 


分割代入

分割代入 (Destructuring assignment) 構文は、配列から値を取り出して、あるいはオブジェクトからプロパティを取り出して別個の変数に代入することを可能にする

var o = {p: 42, q: true}; 
var {p, q} = o; 
 
console.log(p); // 42 
console.log(q); // true 
これは関数の引数で同じことができます。

button.js
export default (props) => { // ここ! 
  var text = typeof props.text !== 'undefined' ? props.text : 'Button' 
  var primary = typeof props.primary !== 'undefined' ? props.primary : false 
  return ( 
    <Wrapper primary={primary}> 
      {text} 
    </Wrapper> 
  ) 
} 
 
const Wrapper = styled.button` 
  padding: 10px; 
  ${(props) => { // ここ! 
    return props.primary && ` 
      background-color: #f99; 
      color: #fff; 
    `} 
  } 
  font-size: 12px; 
` 
もともとオブジェクトである引数を別個の変数に代入して、扱っていたわけですね。


タグ付けされたテンプレートリテラル

テンプレートリテラルの前に式がある場合、テンプレートリテラルは"タグ付けされたテンプレートリテラル"と呼ばれます。この場合、タグ式(通常は関数)は、処理が完了したテンプレートリテラルと一緒に呼び出され、アウトプットの前に実行できます。

var a = 5; 
var b = 10; 
 
function tag(strings, ...values) { 
  console.log(strings[0]); // "Hello " 
  console.log(strings[1]); // " world" 
  console.log(strings[2]); // "" 
  console.log(values[0]);  // 15 
  console.log(values[1]);  // 50 
} 
 
tag`Hello ${ a + b } world ${ a * b}`; 
よくわかりませんが、文字列と${}が、それぞれ第1引数の[0][1]...と、第2,3...引数に、交互に渡されるわけなのですね。

というわけで書き直してみます。

(空白や改行を厳密に再現すると大変なので無視しました!)

button.js
export default (props) => { 
  var text = typeof props.text !== 'undefined' ? props.text : 'Button' 
  var primary = typeof props.primary !== 'undefined' ? props.primary : false 
  return ( 
    <Wrapper primary={primary}> 
      {text} 
    </Wrapper> 
  ) 
} 
 
const Wrapper = styled.button( // ここ! 
  [ 
    'padding: 10px;', 
    'font-size: 12px;' 
  ], 
  (props) => { 
    return props.primary && ` 
      background-color: #f99; 
      color: #fff; 
  `} 
) 
実際に生成されるスタイルもちゃんと下記のようになっていました。

.XXX { 
  padding: 10px; 
  background-color: #f99; 
  color: #fff; 
  font-size: 12px; 
} 


論理演算子(おまけ ES6じゃない)

論理演算子 は、基本的に真偽(論理)値とともに用いられ真偽値を返します。しかし、&& および || 演算子は真偽値ではない値も使うことができるため、その場合は、真偽値ではない値を返すことがあります。

ANDを例にとって解説すると、

true  && true    // t && t true を返します。 
true  && false   // t && f false を返します。 
false && true    // f && t false を返します。 
true && "Dog"    // t && t "Dog" を返します。!! 
"Cat" && "Dog"   // t && t "Dog" を返します。!! 
0 && false       // f && t 0 を返します。!! 
null && true     // f && t null を返します。!! 
 
書き直します。

button.js
export default (props) => { 
  var text = typeof props.text !== 'undefined' ? props.text : 'Button' 
  var primary = typeof props.primary !== 'undefined' ? props.primary : false 
  return ( 
    <Wrapper primary={primary}> 
      {text} 
    </Wrapper> 
  ) 
} 
 
const Wrapper = styled.button( 
  [ 
    'padding: 10px;', 
    'font-size: 12px;' 
  ], 
  (props) => { 
    if (props.primary) { // ここ! 
      return ` 
        background-color: #f99; 
        color: #fff; 
      ` 
    } 
    return props.primary 
  } 
) 


まとめ

理解してしまえば、ES6の記法のほうが断然よいですね!

コメント

このブログの人気の投稿

投稿時間:2021-06-17 22:08:45 RSSフィード2021-06-17 22:00 分まとめ(2089件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)