Statistics Component 화면 구성

score가 이제 local state가 아니라 lifting up 후 공유되기 때문에 합계, high score 등 로직을 짤 수 있게 되었다.

Counter 컴포넌트에 score state를 보관했을때는 전체 score 합계를 구할수 없었지만 App 컴포넌트에 score state를 두게 됨으로써 전체의 score 정보를 알 수 있게 되었다. Stats 컴포넌트를 만들고 Plyaer 합계와 score 합계를 구한다. 먼저 table로 구조를 만든다. webstorm에는 emmet 플러그인이 내장되어있으므로 emmet 구문으로 간단하게 작성한다. div>span*2 후에 탭을 누른다. emmet 구문은 css와 비슷한 구문으로 작성하는데 자세한 것은 Emmet 사이트를 을 참고바란다.

d-flex 클래스로 flex layout을 적용하고, direction은 세로로 정렬해야 하므로 flex-column을 적용한다. 가로 방향 정렬과 세로 방향 정렬은 디폴트로 둔다.

totalPlayers, totalScore는 부모로 부터 players를 물려받아서 계산해야 하는데, 해당 로직은 아래에서 구하고 여기서는 일단 0으로 초기화한다.

components/Statistics.jsx

import React from 'react';

export const Statistics = (props) => {
  const totalPlayers = 0;
  const totalScore = 0;

  return (
    <div className="d-flex flex-column">
      <span>Players: {totalPlayers}</span>
      <span>Total scores: {totalScore}</span>
    </div>
  )
}

Header 컴포넌트에 Statistics 컴포넌트를 추가한다. props로는 players 자체를 넘긴다. div 태그의 첫번째 자식은 삭제한다. 가로 방향 정렬을 space-between 에서 space-around로 변경한다. 

components/Header.jsx

import {Statistics} from "./Statistics";

export const Header = (props) => {
  console.log(props);
  // props는 read only 이다. 아래와 같이 하면 안된다.
  // props.totalPlayers = 12;
  return (<div className="header d-flex justify-content-around align-items-center p-2">
    <h1>{props.title}</h1>
    <Statistics players={props.players}></Statistics>
  </div>)
};

Statistics components 모델 데이터

App => Header => Statistics 순으로 데이터를 흐르게 한다. App 컴포넌트에서 players 를 속성으로 Header 컴포넌트로 넘긴다.

App.jsx

...
        <Header title="My scoreboard" players={this.state.players} />
...

Header 컴포넌트에서도 players 속성을 받은후 자식인 Statistics 컴포넌트로 이미 넘겼다.

Statistics 컴포넌트에서는 전체 player 수와 전체 Score 합계를 구한다.

합계를 구하는 자바스크립트는 없다. 0으로 변수를 초기화하고 루프를 돌면서 계속 더하면서 구해야 한다.

자바스크립트 개발을 계속하게 되면 거의 필연적으로 사용하게 되는 라이브러리중에 하나가 lodash인데 lodash의 sumBy 함수를 사용해서 합계를 구해보자.

먼저 lodash 라이브러리를 인스톨한다.

npm i -S lodash

lodash documentation 에서 sum, sumBy로 검색해보고 충분히 codepen 같은데서 한번 사용해보고 충분히 숙지하고 적용해보는게 좋을것이다.

components/Statistics.jsx

import React from 'react';
import _ from 'lodash';

export const Statistics = (props) => {
  const totalPlayers = props.players.length;
  const totalScore = _.sumBy(props.players, 'score');

  return (
    <div className="d-flex flex-column">
      <span>Players: {totalPlayers}</span>
      <span>Total scores: {totalScore}</span>
    </div>
  )
}