[강제로 배열길이 늘리기] - Array.prototype.fill #리액트 2차 개인과제

간단한 과제 소개

  • 포켓몬 데이터 목록을 이용하여 나만의 포켓몬을 추가/삭제할 수 있다. 
  • 포켓몬 상세 정보를 확인할 수 있다.


페이지 레이아웃은 대충 저렇게 생겼다. 하단 포켓몬 카드의 `추가` 버튼을 누르면 상단 대시보드(나만의 포켓몬)영역에 추가된 포켓몬 카드가 나타난다. 대시보드 카드의 개수를 최대 6개로 정했다. 그럼 추가되지 않은 영역에는 포켓볼 사진을 보여주고 추가된 영역에는 포켓몬 카드를 보여주고 싶다. 여러가지 방법이 있겠으나 `fill()` 메서드를 이용해서 구현했다.

 

 

 

💡 동적으로 UI 출력하기

6개의 고정된 자리가 있다. 추가된 포켓몬은 카드형식으로 보여주고 남는 자리에는 포켓볼 사진을 채워야한다.

 

📍 사용된 컴포넌트와 상태값 (fill 사용 관련)

`selectedPokemon`

  • 추가된 포켓몬 정보를 저장하는 state
  • 포켓몬 데이터의 id를 배열로 가지고 있다.

`Dashboard`

  • 대시보드 컴포넌트
  • 길이 6인 배열을 반복시켜 `PokemonCard` 컴포넌트를 보여준다.

`PokemonCard`

  • 포켓몬 카드 컴포넌트
  • `cardType` props에 따라 포켓볼 혹은 포켓몬카드를 반환한다.

 

그러면 `selectedPokemon`의 길이에 관계 없이 6번을 반복해야 한다. 일반적인 js 문법이라면 고민하지 않고 `for`문을 사용했을텐데 jsx문법에서는 배열메서드로 해결해야하고 `for(let i=0; i<6; ...)` 처럼 반복문의 횟수를 맞추기 위해 `fill()`을 사용했다.

 

📍 fill 사용

const Dashboard = ({ selectedIndex, text, action, MAX_LENGTH = 6; }) => {
  const pokemonList = MOCK_DATA.filter((_, index) => {
    return selectedIndex.includes(index) ? true : false;
  });

  const pokemonListLength = pokemonList.length;

  const filledList = pokemonList.concat(
    new Array(MAX_LENGTH - pokemonListLength).fill(null)
  );

코드 설명 

  • `new Array()`의 인자로 길이를 넣어준다. (최대길이 - 추가된 포켓몬 배열 길이)
  • 메서드 체이닝 기법을 이용하여 `fill(null)` 을 호출한다. 
  • 그러면 해당 길이만큼 null이 채워진 배열을 반환해준다
  • 반환받은 `null` 배열을 원본 배열인 포켓몬데이터에 `concat()`으로 합쳐준다.

그러면 `기존 배열` + `길이만큼 null로 채워진 배열`이 완성된다.

 

📍 컴포넌트 호출하기

위에서 배열을 완성했으면 대충 이렇게 생긴 배열이 완성된다. `[{id:1, name:'대충 포켓몬'} ... null, null, null]`

이제 jsx에서 map을 이용해서 조건부로 컴포넌트에 props를 분기해서 넣어주면 된다.

{filledList.map((pokemon, index) => {
  return !pokemon ? (
    <PokemonCard key={index} cardType="empty" />
  ) : (
    <PokemonCard
      key={`dashboard${pokemon.id - 1}`}
      {...pokemon}
      action={action}
      text={text}
      index={pokemon.id - 1}
      navigateToDetail={navigateToDetail}
    />
  );
})}

코드 설명

  1. pokemon이 falsy한 값이면 cardType에 empty를 전달한다. 
  2. truthy한 값이면 포켓몬 데이터를 전달한다. 

그 후 PokemonCard에서 알잘딱하게 조건 처리하면 끝

 

 

댓글

Designed by JB FACTORY