[React] 중간미션

youngseo·2022년 5월 17일
0

REACT

목록 보기
14/52
post-thumbnail

중간미션

어떤 가게에서 매달, 방문 시에 받은 명함으로 3명을 랜덤하게 추첨하여 할인권을 증정하는 이벤트를 진행하고 있습니다.

  1. 데이터 초기화
    명함 리스트는 데이터 베이스에 저장되어 있습니다.
    우리는 아직 api 를 호출하는 방법을 배우지 않았기 때문에, api 호출 할 필요는 없습니다. 다만 api 호출을 한다고 가정하고, 전달 드리는 명함 리스트를 알맞은 위치에서 초기화 해주세요.

  2. 추첨하기 버튼과 명함 컴포년트 구현
    추첨하기 버튼을 누르면, 1에서 초기화 한 명함 리스트 중 하나의 명함을 고릅니다.
    추첨된 명함 정보를 명함 컴포넌트에 전달하는 방식으로 구현합니다.
    (부모컴포넌트: 추첨하기, 자식 컴포넌트: 명함컴포넌트)

2-1. 상세 조건
추첨하기 버튼을 눌렀을 때, 동일한 사람이 또 다시 추첨되면 안되기 때문에 당첨자는 응답 받은 배열에서 제거합니다.

2-2. 상세 조건
당첨자는 나중에 확인하기 위해, 별도의 데이터로 저장하고 있어야 합니다.

참고 사항
명함 컴포넌트의 디자인은 없어도 괜찮습니다.
명함 리스트가 초기화 되기 전까지, 명함 컴포넌트는 렌더링 되지 않습니다. 명함리스가 초기화되기 전까지는 추첨하기 버튼도 보이지 않습니다.

추첨하기 버튼을 두(n)번째 눌렀을 때, 이전에 처음(n-1) 그렸던 명함은 사라지고 두번 째 명함 정보만 렌더링 되면 됩니다.

  1. 추첨 완료 기능 구현
    추청하기 버튼을 4번 째 누르면, “이미 3명의 추첨을 완료했습니다. 당청자는 AAA, BBB, CCC 입니다.” 라는 window.alert 을 띄운다.

풀이

코드 베이스

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

App.js(부모)

import React from "react";

export default function App() {
  return <div>App</div>
}

BusinessCard.js(자식)

import React from "react";

export default function BusinessCard() {
  return <div>BusinessCard</div>
}

1. 데이터 초기화

전달 드리는 명함 리스트를 알맞은 위치에서 초기화 해주세요.
=> 컴포넌트가 처음 마운트 되었을 때 호출될 수 있도록 해야하기 떄문에 useEffect를 가져와 사용을 합니다. 또한 컴포넌트가 마운트된 직후 딱 한번만 실행이 될 것이기 때문에 의존성 배열로는 빈 배열을 넣습니다. 이런경우 componentDidmount와 똑같이 동작을 하게 됩니다.

import React, { useEffect, useState } from "react";
import datas from './data.cards'

export default function App() {
  const [cards, setCards] = useState([])

  useEffect(() => {
    setCards(datas)
    
  }, []);

  return <div>App</div>;
}

2. 추첨하기 버튼과 명함 컴포넌트 구현

추첨하기 버튼 구현

import React, { useEffect, useState } from "react";
import datas from './data/cards.js'

export default function App() {
  const [cards, setCards] = useState([])
  const [pickedCards, setPickedCards] = useState([])

  function draw() {
    //추첨하기 버튼을 누르면, 랜덤하게 하나의 명함을 고른다.
    const randomIdx = Math.floor(Math.random() * cards.length)
    const randomItem = cards[randomIdx]

    //중복제거
    setCards(cards.filter(c => c.phoneNumber !== randomItem.phoneNumber))

    //당첨자(array) 관리
    setPickedCards([...pickedCards, randomItem])
  }

  useEffect(() => {
    setCards(datas)
    
  }, []);

  console.log(cards)
  console.log(pickedCards)

  return (
    <div>
      { cards.length > 0 && <button onClick={draw}>추첨하기</button> }
    </div>
  );
}

명함 컴포넌트 구현

App.js

import React, { useEffect, useState } from "react";
import datas from './data/cards.js'
import BusinessCard from "./components/BusinessCard";

export default function App() {
  const [cards, setCards] = useState([])
  const [pickedCards, setPickedCards] = useState([])

  function draw() {
    //추첨하기 버튼을 누르면, 랜덤하게 하나의 명함을 고른다.
    const randomIdx = Math.floor(Math.random() * cards.length)
    const randomItem = cards[randomIdx]

    //중복제거
    setCards(cards.filter(c => c.phoneNumber !== randomItem.phoneNumber))

    //당첨자(array) 관리
    setPickedCards([...pickedCards, randomItem])
  }

  useEffect(() => {
    setCards(datas)
    
  }, []);


  return (
    <div>
      { cards.length > 0 && <button onClick={draw}>추첨하기</button> }
      {pickedCards.length > 0 && (
        <BusinessCard info={pickedCards[pickedCards.length-1]}/>
      )}
    </div>
  );
}

BusinessCard.js

import React from "react";

export default function BusinessCard(props) {
  console.log(props);
  const {company, team, name, phoneNumber, email} = props.info
  return (
  <div>
    <div>회사: {company}</div>
    <div>: {team}</div>
    <div>이름: {name}</div>
    <div>휴대번호: {phoneNumber}</div>
    <div>이메일: {email}</div>
  </div>
  );
}

3. 추첨 완료 기능 구현

import React, { useEffect, useState } from "react";
import datas from './data/cards.js'
import BusinessCard from "./components/BusinessCard";

export default function App() {
  const [cards, setCards] = useState([])
  const [pickedCards, setPickedCards] = useState([])

  function draw() {
    //조건추가
    if(pickedCards.length > 2) {
      const names = pickedCards.reduce((acc, cur) => {
        return acc = acc.concat(`${cur.name}, `)
      }, "")

      return  alert(`당첨자는 ${names} 입니다.`)
  
    }

    //추첨하기 버튼을 누르면, 랜덤하게 하나의 명함을 고른다.
    const randomIdx = Math.floor(Math.random() * cards.length)
    const randomItem = cards[randomIdx]

    //중복제거
    setCards(cards.filter(c => c.phoneNumber !== randomItem.phoneNumber))

    //당첨자(array) 관리
    setPickedCards([...pickedCards, randomItem])
  }

  useEffect(() => {
    setCards(datas)
    
  }, []);


  return (
    <div>
      { cards.length > 0 && <button onClick={draw}>추첨하기</button> }
      {pickedCards.length > 0 && (
        <BusinessCard info={pickedCards[pickedCards.length-1]}/>
      )}
    </div>
  );
}

0개의 댓글