[react]反応を処理する技術-第9章素子造形


プロジェクトで自動的に作成されたsrc/App.jssrc/App.cssを使用して、異なる構成部品のモデリングを理解します.
  • App.js
  • import React, { Component } from ‘react‘;
    import logo from./logo.svg‘;
    import./App.css‘;
    
    class App extends Component {
      render() {
        return (
          <div className=“App“>
            <header className=“App-header“>
              <img src={logo} className=“App-logo“ alt=“logo“ />
              <p>
                Edit <code>src/App.js</code> and save to reload.
              </p>
              <a
                className=“App-link“
                href=“https://reactjs.org“
                target=“_blank“
                rel=“noopener noreferrer“
              >
                Learn React
              </a>
            </header>
          </div>
        );
      }
    }
    
    export default App;
  • App.css
  • .App {
      text-align: center;
    }
     
    .App-logo {
      animation: App-logo-spin infinite 20s linear;
      height: 40vmin;
    }
     
    .App-header {
      background-color: #282c34;
      min-height: 100vh;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      font-size: calc(10px + 2vmin);
      color: white;
    }
     
    .App-link {
      color: #61dafb;
    }
     
    @keyframes App-logo-spin {
      from {
        transform: rotate(0deg);
      }
      to {
        transform: rotate(360deg);
      }
    }

    最も一般的な方法、通常のCSS


    CSSを記述する上で最も重要なのは、CSSクラスを重複させないことです.

  • 命名規則
    自動生成App.cssを表示すると、クラス名に構成部品名(ex:App-header)が含まれていることがわかります.また、クラスがどこで使用されるかを明確に記述する方法(ex:.card__title-primary)であるBEMネーミングと呼ばれるCSSメソッドもある.

  • CSS Selector
    スタイルの機能は、CSSクラスが特定のクラスの内部にある場合にのみ適用されます.たとえば、.App.logoにスタイルを適用する場合は、クラス名をより簡単に変更できます.
  • .App {
      text-align: center;
    }
    
    
    /.App 안에 들어 있는 .logo/
    .App .logo {
      animation: App-logo-spin infinite 20s linear;
      height: 40vmin;
    }
    
    /* .App 안에 들어 있는 header 
       header 클래스가 아닌 header 태그 자체에
       스타일을 적용하기 때문에 .이 생략 */
    .App header {
      background-color: #282c34;
      min-height: 100vh;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      font-size: calc(10px + 2vmin);
      color: white;
    }
    
    /* .App 안에 들어 있는 a 태그 */
    .App a {
      color: #61dafb;
    }
    
    @keyframes App-logo-spin {
      from {
        transform: rotate(0deg);
      }
      to {
        transform: rotate(360deg);
      }
    }
    したがって、コンポーネントのJSX部分も修正される.
    import React, { Component } from 'react';
    import logo from './logo.svg';
    import './App.css';
     
    class App extends Component {
      render() {
        return (
          <div className="App">
            <header>
              <img src={logo} className="logo" alt="logo" />
              <p>
                Edit <code>src/App.js</code> and save to reload.
              </p>
              <a
                href="https://reactjs.org"
                target="_blank"
                rel="noopener noreferrer"
              >
                Learn React
              </a>
            </header>
          </div>
        );
      }
    }
     
    export default App;
    このように、コンポーネントの最上位html要素では、コンポーネントの名前をクラス(.App)と命名し、その内部に小文字(.logoheader)を入力し、クラス名を必要としない場合は、直接クラス名を省略することができる.

    拡張CSS構文、Sass


    Sass(システム美観スタイルシート、構文スタイルシート)はCSSフロントプロセッサであり、複雑なタスクを簡単に実行できます.また,スタイルコードの再利用性とコードの可読性が向上し,メンテナンスが容易になった.
    Sassは.sass.scssの2つの拡張子をサポートしています.以下に示すように、カッコとセミコロンの使用部分は少し異なります.しかし、通常.scss文法はもっとよく使われています..sass
    $font-stack: Helvetica, sans-serif
    $primary-color: #333
    body
      font: 100% $font-stack
      color: $primary-color
    .scss
    $font-stack: Helvetica, sans-serif;
    $primary-color: #333;
    body {
      font: 100% $font-stack;
      color: $primary-color;
    }
  • SassComponent.scss
  • // 변수 사용하기
    $red: #fa5252;
    $orange: #fd7e14;
    $yellow: #fcc419;
    $green: #40c057;
    $blue: #339af0;
    $indigo: #5c7cfa;
    $violet: #7950f2;
    // 믹스인 만들기(재사용되는 스타일 블록을 함수처럼 사용할 수 있음)
    @mixin square($size) {
      $calculated: 32px * $size;
      width: $calculated;
      height: $calculated;
    }
    
    
    .SassComponent {
      display: flex;
      .box { // 일반 CSS에서는 .SassComponent .box와 마찬가지
        background: red; 
        cursor: pointer;
        transition: all 0.3s ease-in;
        &.red {
          // .red 클래스가 .box와 함께 사용되었을 때
          background: $red;
          @include square(1);
        }
        &.orange {
          background: $orange;
          @include square(2);
        }
        &.yellow {
          background: $yellow;
          @include square(3);
        }
        &.green {
          background: $green;
          @include square(4);
        }
        &.blue {
          background: $blue;
          @include square(5);
        }
        &.indigo {
          background: $indigo;
          @include square(6);
        }
        &.violet {
          background: $violet;
          @include square(7);
        }
        &:hover {
          // .box에 마우스를 올렸을 때
          background: black;
        }
      }
    }
  • SassComponent.js
  • import React from ‘react‘;
    import./SassComponent.scss‘;
    
    
    const SassComponent = () => {
      return (
        <div className=“SassComponent“>
          <div className=“box red“ />
          <div className=“box orange“ />
          <div className=“box yellow“ />
          <div className=“box green“ />
          <div className=“box blue“ />
          <div className=“box indigo“ />
          <div className=“box violet“ />
        </div>
      );
    };
    export default SassComponent;

    順番に赤ジュノ超波男宝!

    分離utils関数


    複数のファイルで使用できるSass変数と混入は、それぞれ異なるファイルに作成し、必要な場所で容易にロードして使用することができます.srcディレクトリにstylesというディレクトリを作成し、utils.scssファイルを作成します.次に、既存のSassComponent.scssで作成された変数とミキサをutils.scssに移動し、必要な場所で@import操作を実行します.
  • src/styles/utils.scss
  • // 변수 사용하기
    $red: #fa5252;
    $orange: #fd7e14;
    $yellow: #fcc419;
    $green: #40c057;
    $blue: #339af0;
    $indigo: #5c7cfa;
    $violet: #7950f2;
    
    
    // 믹스인 만들기(재사용되는 스타일 블록을 함수처럼 사용할 수 있음)
    @mixin square($size) {
      $calculated: 32px * $size;
      width: $calculated;
      height: $calculated;
    }
  • SassComponent.scss
  • @import './styles/utils';
    .SassComponent {
      display: flex;
      .box {
        background: red; // 일반 CSS에서는 .SassComponent .box와 마찬가지
        cursor: pointer;
        transition: all 0.3s ease-in;
        (...)
      }
    }

    CSS Module


    CSSモジュールは、CSSの読み込みと使用時にクラス名を一意の値、すなわち「ファイル名クラス名ハッシュ値」として自動的に作成し、構成部品スタイルクラス名の重複を防止する技術である.
    srcディレクトリにCSSModule.module.cssというファイルを作成し、次のようにします.
    /* 자동으로 고유해질 것이므로 흔히 사용되는 단어를 클래스 이름으로 마음대로 사용 가능 */
    
    .wrapper {
      background: black;
      padding: 1rem;
      color: white;
      font-size: 2rem;
    }
    
    /* 글로벌 CSS를 작성하고 싶다면 */
    
    :global .something {
      font-weight: 800;
      color: aqua;
    }
    上記のファイルは、直接読み込まれた構成部品の内部でのみ動作するため、クラスの名前を付けるときに一意性を考慮する必要はありません.
    書き終わったら、上記CSSモジュールを使った反応素子も書きましょう!
  • CSSModule.js
  • import React from ‘react‘;
    import styles from./CSSModule.module.css‘;
    const CSSModule = () => {
      return (
        <div className={styles.wrapper}>
          안녕하세요, 저는 <span className=“something“>CSS Module!</span>
        </div>
      );
    };
    
    
    export default CSSModule;
    CSSモジュールが適用されたスタイルファイルをインポートすると、CSSモジュールで使用されるクラス名とキー値として名前が付けられた値を含むオブジェクトが渡されます.たとえば、上記のコードのconsole.log(styles)には、次の結果が表示されます.
    { wrapper: “CSSModule_wrapper__1SbdQ” }
    この一意のクラス名を使用するには、クラス名をclassName = {styles.클래스 이름}としてクラスを適用したいJSXエイリアスに渡すだけです.:globalグローバル宣言を使用するクラスについては、通常のように文字列に挿入します.

    JSファイルに組み込まれたスタイル、styled-complements


    「JavaScriptファイルでスタイルを宣言することで、スタイルファイルを作成する必要はありません.」CSS-In-JSと呼ばれ、npmまたはyarnにインストールする必要があります.
    npm install --save styled-components
  • StyledComponent.js
  • import React from ‘react‘;
    import styled, { css } from ‘styled-components‘;
    
    const Box = styled.div`
      /* props로 넣어 준 값을 직접 전달해 줄 수 있다. */
      background: ${props => props.color || 'blue'};
      padding: 1rem;
      display: flex;
    `;
    
    const Button = styled.button`
      background: white;
      color: black;
      border-radius: 4px;
      padding: 0.5rem;
      display: flex;
      align-items: center;
      justify-content: center;
      box-sizing: border-box;
      font-size: 1rem;
      font-weight: 600;
    
      /* & 문자를 사용하여 Sass처럼 자기 자신 선택 가능 */
      &:hover {
        background: rgba(255, 255, 255, 0.9);
      }
    
      /* 다음 코드는 inverted 값이 true일 때 특정 스타일을 부여해 준다. */
      ${props =>
        props.inverted &&
        css`
          background: none;
          border: 2px solid white;
          color: white;
          &:hover {
            background: white;
            color: black;
          }
        `};
      & + button {
        margin-left: 1rem;
      }
    `;
    
    const StyledComponent = () => (
      <Box color=“black“>
        <Button>안녕하세요</Button>
        <Button inverted={true}>테두리만</Button>
      </Box>
    );
    
    export default StyledComponent;