컴포넌트 지향으로 react-redux로 화면을 만드는 아이디어

개요



컴퍼넌트 지향에 대해, 알았던 것 같은 신경이 쓰여 실제로 만들어 보면 여러가지 엉망이 되어 버렸지만, 다시 생각을 정리하면 조금 잘 가게 되었다.

능숙해지지 않았을 때와, 능숙해진 지금의, 사고방식의 diff를 씹으면서 정리했으므로 이하에 소개한다.

react-redux를 사용하여 일반적인 목록 화면을 만드는 것을 가정하면서 소개

전제


  • webpack 등을 사용한 js · jsx의 빌드와 트랜스 파일이 있다고 전제

  • 아이디어 1 · 구성 요소가 처음



    어쨌든, 성분으로 만든다.

    예를 들면 이런 느낌의 화면을 만드는 것을 생각한다. (점포 일람 화면)


    로드하는 동안 이렇게


    화면에서 사용할 컴포넌트를 먼저 열거한다.
    아마 이런 느낌



    각 구성 요소를 구현합니다. 어떤 props가 있으면 좋은가를 생각하면서 구현한다.
    기존 세상에 있는 컴퍼넌트도 적절히 사용한다(여기에서는 most poular이다 Material-UI 를 사용한다.그 경우도 적절히 랩 하거나 한다.)
    아마 이런 느낌. 괄호 안에는 필요한 것 같은 props와 처리
    - Atoms
        - TextField (Enter押した時のハンドラ、placeholder、など)
        - IconButton (アイコンの種類、クリックした時のハンドラ、など)
        - Button (クリックした時のハンドラ、など)
    
    - Molecules
        - SearchBox (ボタンクリックやEnterを押した時のハンドラ/ハンドラのトリガ)
    
    - Organisms
        - BranchCard (店舗ID、店舗名、店舗住所、など)
        - BranchList (店舗情報リスト)
        - Pagination (現在の表示数、合計数、次があるか、前があるか、など/前、次を押した時のハンドラ)
        - Loading (特になし)
    
    - Templates
        - ListPageTemplate (ヘッダ部分のコンポーネント、リスト部分のコンポーネント、ページナビ部分のコンポーネント、ローディング表示かどうか)
    
    - Pages
        - BranchesListPage (ajaxで取得した店舗リスト、データ取得中かどうか、現在の検索条件/マウント時にデータ取得、ページ移動した時にデータ取得・URL変更、ListPageTemplateに各コンポーネントを渡してrender、など)
    

    Atoms나 Molecules 등은 특히 범용성이 높아지도록 만든다. 예를 들어 Atoms나 Molecules 등의 부품으로 margin 설정하는 것이 정적.

    atomic design 정보



    다음을 알기 쉽다.

    SlideShare
    UI 개발을 애자일하게 하기 위한 Atomic Design


    Atomic Design ~ 견고하고 사용하기 쉬운 UI를 효율적으로 설계

    아이디어 2 · 구성 요소에 필요한 props를 기반으로 Reducer 구현



    컴퍼넌트를 생각하고 나서 reducer 를 구현한다. reducer를 먼저 생각해 컴퍼넌트를 거기에 맞추도록(듯이) 구현하는 것은 아니다.
    앞서 열거한 컴퍼넌트 중에서, reducer가 필요한 것은 margin 다른 사람은 부모에게서 props를 배달한다.

    예를 들면 이런 느낌의 reducer가 된다
    import { LOCATION_CHANGE } from 'react-router-redux';
    import {
      REQUEST_BRANCHES,
      RECEIVE_BRANCHES,
      REQUEST_BRANCHES_FAILURE,
    } from '~/constants/actionTypes';
    
    const initialState = {
      loading: false,   // ロード中かどうか。Loadingを描画するかどうかの判定で使う
      search: '',       // 検索ワード。表示したり、TextFieldにあらかじめ表示しておくなら使う
      total: 0,         // データの合計数。表示するので使う
      page: 0,          // 現在のページ。表示したり、次や前へを押せるか、また押した時に、どうリクエストを送るのかに使う
      rowsPerPage: 5,   // 1ページあたりの件数。表示したり、次や前へを押せるか、また押した時に、どうリクエストを送るのかに使う
      offset: 0,        // 現在何件目からを表示しているのか。表示したり現在のページの計算に使う
      items: [],        // 表示するデータ。表示するのに使う
    };
    
    export default function branchesList(state = initialState, action) {
      switch (action.type) {
        case LOCATION_CHANGE: {
          // URLによってpropsが変わるならここに処理を書く。ここでは省略
        }
        case REQUEST_BRANCHES:
          return {
            ...state,
            loading: true,
          };
        case RECEIVE_BRANCHES: {
          const {
            orders: items,
            offset,
            total,
            limit,
            search,
          } = action.data;
          const page = Math.floor(offset / state.rowsPerPage, 10);
          return {
            ...state,
            loading: false,
            search,
            items,
            offset,
            total,
            page,
          };
        }
        case REQUEST_BRANCHES_FAILURE:
          return {
            ...state,
            loading: false,
          };
        default:
          return state;
      }
    }
    
    

    그리고는 actions나 style를 만들어 끝.

    사고방식 3: 뭔가 변경이 있었을 때도, 컴퍼넌트를 우선해 생각한다



    뭔가 변경이 있었을 때도, 컴퍼넌트를 우선해 생각한다. reducer나 action 있어는 아니고, 컴퍼넌트 있어이다.

    예를 들어, 이 일람 화면에서, 다른 항목을 늘리고 싶지만, 페이지당 표시할 수 있는 건수를 변경할 수 있는 UI를 갖고 싶지만, 검색 조건을 보다 늘리고 싶은, 정렬하고 싶은, 로그인 유저를 헤더에 내고 싶은 등등, 어떤 변경이라도, 그것이 컴퍼넌트에 어떻게 영향을 주는가를 생각한다.

    컴퍼넌트가 표시하는 내용이 어떻게 되는지, 컴퍼넌트가 표시하는 내용을 결정하기 위해서 props가 늘어나거나, 그것을 위해서는 새로운 action이 필요, 새로운 reducer의 구현이 필요, 등, 그러한 순서로 생각한다.

    storybook도 처음부터 만든 것이 컴포넌트가 깨끗하게 만들 수 있는지를 알기 때문에 좋다.
    storybook

    요약



    어쨌든 컴퍼넌트가 먼저, 그 외는 후. 라고 하는 식으로, 생각하면 깨끗이 한 설계가 된다.

    좋은 웹페이지 즐겨찾기