개요

이 글은 강좌가 아닙니다. 부족한 부분이 있더라도, 너그럽게 봐주신다면 감사하겠습니다. 피드백 언제나 환영입니다 :)

시작하기에 앞서, 저번 글에서 interface와 type의 차이에 대해 알려드리기로 했었어요.

type

  • Type은 새로 정의된 타입이 아님
  • extends, implements 불가능

interface

  • Interface는 새로 정의된 타입
  • extends, implements 가능

그래서 interface에 마우스를 가져다대면 interface가, type에 마우스를 가져다대면 객체자체의 타입으로 표시된다고 하네요.

솔직히 저도 잘 모르겠어요. 댓글로 알려주세요.

자 그럼 본론으로 들어가볼게요.

빙고판 꾸미기

App.tsx 파일을 수정해줍니다.

    const [count, setCount] = useState<number>(5);    // 빙고판 크기
    const [shuffled, setShuffled] = useState<Array<string>>([]);    // Shuffle될 이모지 배열

    <div style={{ display: "flex", justifyContent: "center" }}>
      <WhiteFont>개수</WhiteFont>
      <select
        onChange={(e: React.ChangeEvent<HTMLSelectElement>) =>
            setCount(parseInt(e.target.value))
        }
        value={count}
        >
        <option>5</option>
        <option>6</option>
        <option>7</option>
        <option>8</option>
      </select>
    </div>    
    <ShuffleBtn onClick={handleShuffle}>SHUFFLE !</ShuffleBtn>
    <BingoBoard count={count} emojis={shuffled}/>

지난번엔, count를 BingoBoard에서 관리했지만, BingoBoard는 아이템을 띄우는 용도라 생각하고 props로 넘겨주기로 했어요.

BingoBoard.tsx 파일도 수정해줍니다.

    interface Props {
       count: number;
       emojis: Array<string>;    
    }

    const BingoBoard = ({ count, emojis }: Props) => {
       let matrix: Array<Array<Square>> = [];

        ...

       for (let i = 0; i < count; i++) {    
          for (let j = 0; j < count; j++) {
             matrix[i][j] = {
                contents: emojis[i * count + j], // 빙고 아이템들에 이모지를 하나씩 채워요.
                checked: false
             };
          }
       }

      ...

    }

함수 구현

App.tsx

    const shuffle = useCallback((array: Array<string>) => {
        for (let i = array.length - 1; i > 0; i--) {
           const j = Math.floor(Math.random() * (i + 1));
           [array[i], array[j]] = [array[j], array[i]];
        }
        return array;
     }, []);

    const handleShuffle = () => {
       setShuffled(Array.from(shuffle(emojis)));
    };

처음에 함수를 구현하였을 때, 이렇게 짰어요.

    setShuffled(shuffle(emojis));

이렇게 짜니깐 BingoBoard에서는 같은 Array<string>이 props로 내려오니 변화를 감지하지 못해서 렌더링이 다시 되지 않더군요. 그래서 처음 실행한 방법은 idx라는 글로벌 변수를 두고 , {idx, emojis: []} 이런식으로 props를 보냈어요. 하지만 좋은 방법인거 같지 않아서 계속 알아보던중 Array.from() 이란 함수를 썼어요.

Array.from() 메서드는 배열을 복사해 새로운 배열을 만듭니다.
예시: Array.from([1, 2, 3], x => x + x) outputs: [2,4,6]

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/from

BingoBoard.tsx

    for (let i = 0; i < count; i++) {
       for (let j = 0; j < count; j++) {
          matrix[i][j] = {
             contents: emojis[i * count + j],
             checked: false
          };
       }
    }

자, 이제 Shuffle! 이란 버튼을 누르면 빙고판 안의 아이템들이 변하는걸 확인할 수 있어요.

결과물

스크린샷 2019-11-15 오후 12.26.51.png

다음에는

다음에는 빙고 아이템을 고르는 기능을 만들어볼거에요.

저장소

모든 코드와 진행과정은 https://github.com/mango906/EmojiBingo 에서 확인 가능합니다.