React
styled-components

[react:day2] コンポーネントにスタイルを

環境

react:day1.2と同じ

reactでスタイルを書く方法

いろいろ見てみたが特に「これだ!」っていうものも無く、
普通にCSS書いてもいいかな〜なんて思っちゃったりもした。
が、
style: styled-componentsはreact nativeでも使えるみたいなのでこれで書いてみたいと思う。

styled-componentsをinstall

npm install --save styled-components

vs codeにstyled-componentsのsyntaxがあるのでこちらもインストール
スクリーンショット 2018-01-31 14.56.48.png

MemberImageにスタイルを当ててみる

member-image.js
import React, { Component } from 'react';

// styled-componetsをimport
import styled from 'styled-components';

// styleを定義
const Img = styled.img`
  height: 5rem;
  width: 5rem;
`;
export default class MemberImage extends Component {
  render() {
    return(
      <Img src={this.props.memberImage}/>
    );
  }
}

こんな感じになる
スクリーンショット 2018-01-31 15.33.39.png

生成されたHTMLを見ると2つのクラスがついている
スクリーンショット 2018-01-31 15.34.40.png

styled.img を styled.div に変えてみた。

member-image.js
import React, { Component } from 'react';

// styled-componetsをimport
import styled from 'styled-components';

// styleを定義
// const Img = styled.img`
const Img = styled.div`
  height: 5rem;
  width: 5rem;
`;
export default class MemberImage extends Component {
  render() {
    return(
      <Img src={this.props.memberImage}/>
    );
  }
}

生成されるのはdivになる
スクリーンショット 2018-01-31 15.39.57.png

これでなんとなくイメージができた。

propsの値でスタイルを変えてみる

member.js
import React, { Component } from 'react';
import styled from 'styled-components';
import MemberName from './member-name';
import MemberImage from './member-image';

// style
const Wrap = styled.div`
  /* 偶数奇数で背景色を変更 */
  background: ${ props => (props.rowNumber % 2 === 0) ? 'aliceblue':'white'};
`
export default class Member extends Component {
  render() {
    return(
      <div>
        {this.props.memberList.map((member, index) => {
          return (
            // rowNumberを渡す
            <Wrap key={index} rowNumber={index}>
              <MemberName memberName={member.name}/>
              <MemberImage memberImage={member.image}/>
            </Wrap>
          );
        })}
      </div>
    );
  }
}

とりあえずやりたい事はできた
スクリーンショット 2018-01-31 16.14.13.png

しかし、まだよくわかってないところ
- propsのスコープ
- styledの中で${ props => (props){} こう書かないと何故参照できないのか

propsのスコープ

Wrapに設定したrowNumberをMemberNameに書いてみて参照できるかテスト

member.js
import React, { Component } from 'react';
import styled from 'styled-components';
import MemberName from './member-name';
import MemberImage from './member-image';

// style
const Wrap = styled.div`
  /* 偶数奇数で背景色を変更 */
  background: ${ props => (props.rowNumber % 2 === 0) ? 'aliceblue':'white'};
`
export default class Member extends Component {
  render() {
    return(
      <div>
        {this.props.memberList.map((member, index) => {
          return (

            <Wrap key={index}>
              {/* MemberNameにrowNumberをセット */}
              <MemberName  rowNumber={index} memberName={member.name}/>
              <MemberImage memberImage={member.image}/>
            </Wrap>
          );
        })}
      </div>
    );
  }
}

こう表示される。
スクリーンショット 2018-01-31 16.18.41.png

他のタグに書いても値は引き渡されないようだ。

styledの中で${ props => (props){} こう書かないと何故参照できないのか

これはそういう事だとして次に進もうと思う。

media-queryを使ってstyleを変更してみる

とりあえず現状はこんな感じ

member.js
import React, { Component } from 'react';
import styled from 'styled-components';
import MemberName from './member-name';
import MemberImage from './member-image';

// style
const Wrap = styled.div`
  /* 偶数奇数で背景色を変更 */
  background: ${ props => (props.rowNumber % 2 === 0) ? 'aliceblue':'white'};
  display: flex;
  justify-content: center;
`
const MemberGroup = styled.div`
  display:flex;
  flex-direction: column;
`
export default class Member extends Component {
  render() {
    return(
      <div>
        {this.props.memberList.map((member, index) => {
          return (
            <Wrap key={index} rowNumber={index} >
              <MemberGroup>
                <MemberName memberName={member.name}/>
                <MemberImage memberImage={member.image}/>
              </MemberGroup>
            </Wrap>
          );
        })}
      </div>
    );
  }
}

キャプチャ

スクリーンショット 2018-01-31 16.49.21.png

まずはcolorだけ変えてみる

member.js
import React, { Component } from 'react';
import styled from 'styled-components';
import MemberName from './member-name';
import MemberImage from './member-image';

// style
const Wrap = styled.div`
  /* 偶数奇数で背景色を変更 */
  background: ${ props => (props.rowNumber % 2 === 0) ? 'aliceblue':'white'};
  display: flex;
  justify-content: center;

  /* media query */
  @media (min-width: 720px){
    color:red;
  }
`
const MemberGroup = styled.div`
  display:flex;
  flex-direction: column;
`
export default class Member extends Component {
  render() {
    return(
      <div>
        {this.props.memberList.map((member, index) => {
          return (
            <Wrap key={index} rowNumber={index} >
              <MemberGroup>
                <MemberName memberName={member.name}/>
                <MemberImage memberImage={member.image}/>
              </MemberGroup>
            </Wrap>
          );
        })}
      </div>
    );
  }
}

OK
medi.gif

次にwidthで判定して写真の並びを row/column 切り替える

member.js
import React, { Component } from 'react';
import styled from 'styled-components';
import MemberName from './member-name';
import MemberImage from './member-image';

// style
const FlexWrap = styled.div`
  display: flex;
  flex-direction: column;
  /* media query */
  @media (min-width: 720px){
    flex-direction: row;
    justify-content: space-evenly;
  }
`
const Wrap = styled.div`
  /* 偶数奇数で背景色を変更 */
  background: ${ props => (props.rowNumber % 2 === 0) ? 'aliceblue':'white'};
  display: flex;
  justify-content: center;
`
const MemberGroup = styled.div`
  display:flex;
  flex-direction: column;
`
export default class Member extends Component {
  render() {
    return(
      <FlexWrap>
        {this.props.memberList.map((member, index) => {
          return (
            <Wrap key={index} rowNumber={index} >
              <MemberGroup>
                <MemberName memberName={member.name}/>
                <MemberImage memberImage={member.image}/>
              </MemberGroup>
            </Wrap>
          );
        })}
      </FlexWrap>
    );
  }
}

想定通り動く
medi2.gif

スタイルはとりあえずこれでいいかな。
さて、次は何しよう🍪