index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Scoreboard</title>
  <meta
    name="viewport"
    content="width=device-width, initial-scale=1, shrink-to-fit=no"
  />
  <!--  https://getbootstrap.com/docs/5.0/getting-started/download/ 에서 다운로드-->
  <link rel="stylesheet" href="./bootstrap.css">
  <link rel="stylesheet" href="./app.css" />
</head>

<body>
<div id="root"></div>
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel" src="./app.js"></script>
</body>
</html>

app.js

const players = [
  {name: 'LDK', score: 30},
  {name: 'HONG', score: 40},
  {name: 'KIM', score: 50},
  {name: 'PARK', score: 60},
];

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

const Player = (props) => (
  <div className="container">
    <div className='player row align-items-center'>
      <div className="col-1">
        <button className="btn btn-danger"
                onClick={() => props.removePlayer(props.id)}>x</button>
      </div>
      <div className="col-8">
        <span>{props.name}</span>
      </div>
      <div className="col-3 counter">
        <Counter score={props.score} />
      </div>
    </div>
  </div>
);

class Counter extends React.Component {
  state = {
    score: 0
  };

  incrementScore = () => {
    console.log(this);
    this.setState(prevState => {
      return {score: prevState.score + 1}
    });
  }

  decrementScore = () => {
    this.setState(prevState => {
      return {score: prevState.score - 1}
    });
  }

  render() {
    return (
      <div className='d-flex justify-content-between align-items-center'>
        <button className='btn btn-info' onClick={this.decrementScore}> - </button>
        <span>{this.state.score}</span>
        <button className='btn btn-info' onClick={this.incrementScore}> + </button>
      </div>
    );
  }
}

class App extends React.Component {
  state = {
    players: [
      {name: 'LDK', id: 1},
      {name: 'HONG', id: 2},
      {name: 'KIM', id: 3},
      {name: 'PARK', id: 4},
    ]
  };

  handleRemovePlayer = (id) => {
    this.setState(prevState => {
      return {
        players: prevState.players.filter(item => item.id !== id)
      }
    })
  }

  render() {
    return (
      <div className="container p-3">
        <Header title="My scoreboard" totalPlayers={this.state.players.length} />

        {/*Players List*/}
        { this.state.players.map(item =>
          <Player name={item.name} key={item.id}
            removePlayer={this.handleRemovePlayer} id={item.id} />) }
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('root'));

app.css

/* user defined css */
.header {
  background-color: #733daa;
  color: #ffffff;
}

.player {
  font-size: 1.2em;
  border-bottom: solid 2px #EEEEEE;
  border-left: solid 2px #EEEEEE;
  border-right: solid 2px #EEEEEE;
  letter-spacing: 2px;
  height: 4rem;
}

.counter {
  border-left: solid 2px #DDDDDD;
}