steadily
451
2021-09-09 17:20:38 작성 2021-09-09 17:22:15 수정됨
4
94

React 토글 상태관리 질문있습니다.




안녕하세요. 여러개의 토글 버튼이 있고 각각을 눌렀을 때 스타일링을 다르게 주고 싶습니다. 위 사진을 예로 들면 강아지를 클릭했을 때 스타일링을 다르게 주고 싶습니다.

import React, { useState } from 'react'
import styled from 'styled-components/macro'

const ToggleDivWrap = styled.div`
margin: 80px 0;
display: flex;
justify-content: center;
`

const ToggleButtonWrap = styled.div`
top: 319px;
left: 625px;
width: 100px;
height: 50px;
margin: 0 10px;

border: ${(props) => (props.isToggle ? 'none' : '0.2px solid #707070')};
border-radius: 20px;
opacity: 1;
background-color: ${(props) => (props.isToggle ? '#fbf3da' : 'none')};
`

const TextInToggleButton = styled.p`
margin-top: 13%;
text-align: center;
font: normal normal medium 16px/24px Noto Sans CJK KR;
letter-spacing: 0px;
color: ${(props) => (props.isToggle ? '#1d1e20' : '#707070')};
opacity: 1;
`

const animal_list = [
{
id: '1',
name: '강아지',
},
{
id: '2',
name: '고양이',
},
{
id: '3',
name: '',
},
{
id: '4',
name: '오리',
},
{
id: '5',
name: '물고기',
},
{
id: '6',
name: '...',
},
]
const Toggle = () => {
const [isToggle, setIsToggle] = useState(false)
const [toggledLists, setToggledLists] = useState([])

const toggleHandler = (toggled, id) => {
if (toggled) {
setToggledLists([...toggledLists, id])
setIsToggle(true)
} else {
setToggledLists(toggledLists.filter((el) => el !== id))
setIsToggle(false)
}
}
return (
<ToggleDivWrap>
{animal_list.map((animal) => (
<ToggleButtonWrap
key={animal.id}
isToggle={isToggle}
onClick={(e) => {
setIsToggle((isToggle) => !isToggle)
toggleHandler(e.currentTarget.isToggle, 'animal.id')
}}
>
<TextInToggleButton>{animal.name}</TextInToggleButton>
</ToggleButtonWrap>
))}
</ToggleDivWrap>
)
}

export default Toggle

생각해본 코드는 이러한데, onClick 부분에서 setIsToggle이 적용되지 않습니다. 그리고 이때문에 그 아랫줄인 toggleHandler도 isToggle 상태가 바뀌지 않아서 아무런 일이 일어나지 않습니다. (계속 isToggle은 false에 머물러 있습니다.)

제가 궁금한 건 이게 되지 않는 이유, 그리고 이대로 하면 ToggleButtonWrap으로 지정해준 div들의 className이 전부 다 동일해서 스타일링이 한꺼번에 바뀌는 현상을 고치는 방법 입니다.

전문가 분들의 고견을 구해요. 감사합니다.

0
  • 답변 4

  • 당근같은사람
    4
    2021-09-09 17:36:27

    우선 보이는 부분은 toggleHandler 함수를 호출하는 부분에서 전달된 두 번째 인자가 animal.id가 아닌 string 타입의 'animal.id' 이네요.

  • steadily
    451
    2021-09-09 17:47:25

    당근같은사람 선생님 답변 감사합니다.

    말씀하신 부분도 문제가 되긴 했었네요. 콤마를 지워줘도 제대로 실행이 되지 않기는 했습니다만..ㅠㅠ

    감사합니다.

  • 오키동키
    82
    2021-09-09 19:40:44 작성 2021-09-09 19:43:27 수정됨

    제가 사용하는 하나씩 바꾸는 방법은 

    const [current, setCurrent] = useState(0) 만들고

    map array에 key값 밑에 id={index}

    와 같이 만들어 컴포넌트에 전달후 className에 

    className = {e.target.id = current && ‘active-style‘} 

    와 같이 사용합니다 !참고해보셔요

  • 당근같은사람
    4
    2021-09-09 20:28:57

    https://codesandbox.io/s/toggletest-fonu2


    toggle 상태에 따라 버튼의 색상이 바뀌는 테스트 컴포넌트를 만들어 봤습니다.

    위 링크 코드가 구현하시고자 하는 방향이랑 맞길 바랍니다. ㅎㅎ

  • 로그인을 하시면 답변을 등록할 수 있습니다.