react) map함수 클릭 이벤트에서 한개의 값만 스타일 변경하기

이명진·2021년 4월 16일
4

react - 이론

목록 보기
6/11

이전에는 클릭시 스타일만 변경하는 방법을 작성하였다. 하지만 홈페이지를 보면 하나만 클릭했을시 하나만 불이 들어온다거나 하나만 스타일이 변경되어야 한다.

이전 방법에서 발전시켜 어떻게 진행해야 할지 고민을 많이 했는데 이것은 새롭게 접근해야 했다.

이번의 핵심은 클릭되었을때 그 클릭한 것의 인덱스 값을 받아와서
그 클릭한 개체에게 신호를 보내주는 것

멘토님께 방법에 대해서 들었지만 한번 듣고나서는 이해하기 어려웠고
마침 두곳에 이 기능을 적용해야 했기에 한번은 다시 작성해보고
벨로그에 다시 작성을 하면서 익숙해 지도록 노력하였다.

기능 구현

가장 쉽게 생각해보자면 전체에게 false 값을 지정해주고 선택된 개체만 true로 변경해주며 스타일을 적용해주는 것이다. 말로는 쉽지만 코드를 짜기에는 접근하기 어려웠다.

부모 코드

render 이전의 함수와 state부분을 먼저 살펴보자.

 constructor() {
    super();
    this.state = {
      
      isCategorySelect: Array(TITLES.length).fill(false),
    };
  }
  handleClick = idx => {
    const newArr = Array(TITLES.length).fill(false);
    newArr[idx] = true;
    this.setState({
      isCategorySelect: newArr,
   
    });
  };

state값은 isCategorySelect값을 만들어 주는데
배열로 값을 받게 된다. 배열의 개수는 적용된 개체의 개수만큼 false로 채워준다.

함수를 handleClick으로 만들어 주고 idx 인덱스 값을 받게 된다.
여기서 newArr변수를 생성하여 새로 array를 만들어 주는데
기존의 array값에서 index값을 받은 것만 true로 변경해줘야 하기 때문에
새로운 배열을 만들어 주는 작업을 해준다.
그리고 함수가 실행되면 setState를 통해서 newArr의 배열에서 선택된 index값만 true로 바꾼 값으로 변경해준다.

렌더링 이후 부분을 살펴본다.

{TITLES.map((elm, index) => {
                return (
                  <Category
                    key={index}
                    isSelected={isCategorySelect[index]}
                    handleClick={this.handleClick}
                    elementIndex={index}
                  />
                );
              })}

TITLES라는 값을 미리 만들어 두었다. TITLES는 배열안에 객체가 들어간 모습을 생겼다.
맵함수를 실행하는데 각각의 인덱스 개체와 index값을 받는다 .
받은 값을 자식 컴포넌트에 isSelected , handleClick , elementIndex 값을 받아서 전달해 줍니다.
isSelected는 isCategorySelect의 인덱스를 전달해주고
handleClick은 handleClick함수를 전달해주고
elementIndex는 index 인덱스를 전달해줍니다.

맵함수는 TITLES의 배열의 값들을 전달받아서 category(자식 컴포넌트)를 반복적으로 생성하게 됩니다.

자식 컴포넌트

자식 컴포넌트를 살펴 봅니다.

const { icon, content, isSelected, handleClick, elementIndex } = this.props;
    return (
      <li
        className={`buttonList ${isSelected ? 'true' : 'false'}`}
        onClick={() => handleClick(elementIndex)}
       
      >

자식 컴포넌트는 생각보다 간단해졌습니다. 함수 등을 생성하지 않고
바로 렌더링하는데 li에서 isCategorySelect 값을 isSelected값으로 받았기 때문에 true일 경우에는 스타일을 변경하고 false일경우에는 기존 스타일을 받아 쓰게 삼항 연산자를 활용하였습니다.

중요한 점이 onclick을 할때 함수를 바로 실행하지 않기 위해서
() => handleClick(elementIndex) 이런식으로 함수를 정의 해줍니다.

이러면 클릭때마다 elementIndex를 인자를 받고 함수를 실행하게 됩니다.

그러면 이렇게 기능이 구현이 됩니다.

머리로는 이해하는데 직접 코드를 짜며 구현하는 것은 많은 어려움을 느낀다.
자주 사용하면서 반복 숙달이 필요할것 같다.ㅠㅠ

profile
프론트엔드 개발자 초보에서 고수까지!

1개의 댓글

comment-user-thumbnail
2021년 8월 19일

감사합니다!~많은 도움이 되었습니다. 리액트로 하자면 이렇게 될 것 같습니다.
const [isBoxSelect, setBoxSelect] = useState([false, false]);
const handleIDX = (IDX: any) => {
const newArr = Array(gridRealData.length).fill(false);
newArr[IDX] = true;
setBoxSelect(newArr);
};

답글 달기