-
[React] Footer 이미지 누를때마다 상태변화 (useState)프론트앤드/[React] 2023. 3. 28. 15:54728x90
오늘도 여전히 기업협업 중이다..
오늘은 Footer를 하다가 막히는 부분을 뚫어보았기 때문에 이렇게 글을 써본당..히히
구현하고자 한것
하나하나 누른것들만 주황색 글씨와 그림이 바뀌게 해야했다.
맨처음 구현한 코드
import React, { useState } from 'react'; import * as S from './Footer.style'; import FOOTER_LIST from './FooterList'; const Footer = () => { const [clicked, setClicked] = useState(false); const handleClicked = () => { return setClicked(!clicked); }; return ( <S.FooterContainer> <S.FooterUl> {FOOTER_LIST.map(footer => { return ( <S.FooterList key={footer.id} onClick={handleClicked}> <S.FooterImg src={clicked ? footer.checkedImg : footer.defaultImg} alt="img" /> {footer.title} </S.FooterList> ); })} </S.FooterUl> </S.FooterContainer> ); }; export default Footer; const FOOTER_LIST = [ { id: 1, title: '홈', defaultImg: './images/storefront.png', checkedImg: './images/store.png', }, { id: 2, title: '자주가요', defaultImg: './images/favorite.png', checkedImg: './images/colorFavorite.png', }, { id: 3, title: '전단 등록', defaultImg: './images/upload.png', checkedImg: './images/colorUpload.png', }, { id: 4, title: '마이페이지', defaultImg: './images/mypage.png', checkedImg: './images/colorMypage.png', }, ];
나는 img의 색을 바꾸기 보다는 색깔을 입힌 이미지가 준비되어 있어서 defaultImg 와 checkedImg 로 따로 이미지를 준비했다.
여기서 발생한 문제는 하나하나씩 상태관리가 가능했지만, 다른하나를 눌렀을때 여전히 색깔을 입힌 이미지가 화면상으로 나왔다는 것이다.
이게 은근히 어렵더라.. -_ㅠ
변경된 코드
const Footer = () => { const [clickedIndex, setClickedIndex] = useState(0); const handleClicked = index => { setClickedIndex(index); }; return ( <S.FooterContainer> <S.FooterUl> {FOOTER_LIST.map((item, index) => ( <div key={index}> <S.FooterList onClick={() => handleClicked(index)} isClicked={index === clickedIndex} > <S.FooterImg src={index === clickedIndex ? item.checkedImg : item.defaultImg} /> <S.FooterTitle> {item.title}</S.FooterTitle> </S.FooterList> </div> ))} </S.FooterUl> </S.FooterContainer> ); };
설명)
const [clickedIndex, setClickedIndex] = useState(0);
const handleClicked = index => { setClickedIndex(index); };clickedIndex라는 상태 변수와 handleClicked라는 함수를 선언했다.
clickedIndex 변수는 현재 클릭된 이미지의 인덱스 값을 저장하며, handleClicked 함수는 이미지 클릭 이벤트가 발생할 때마다 해당 이미지의 인덱스를 clickedIndex에 저장하여 업데이트한다.
<S.FooterUl> {FOOTER_LIST.map((item, index) => ( <div key={index}> <S.FooterList onClick={() => handleClicked(index)} isClicked={index === clickedIndex} > <S.FooterImg src={index === clickedIndex ? item.checkedImg : item.defaultImg} /> <S.FooterTitle> {item.title}</S.FooterTitle> </S.FooterList> </div> ))} </S.FooterUl>
S.FooterList 컴포넌트의 onClick 핸들러 함수를 handleClicked 함수로 설정하고,
S.FooterImg 컴포넌트의 src 속성을 clickedIndex 상태 변수와 비교하여, 클릭된 이미지에 대해서만 checkedImg를 설정하고 아닌경우에는 defaultImg를 설정했다.
이렇게 하니, 내가 원했던 기능이 구현이 되었다.!!
추가로 홈, 자주가요 , 전단등록, 마이페이지 글씨 색깔도 변경을 같이 해주고 싶었다.
내가 사용한것은 styled.components 이다.
<S.FooterList onClick={() => handleClicked(index)} isClicked={index === clickedIndex} > 여기서 사용된 isClicked 를 스타일드컴포넌트로 변화를 주었다. export const FooterList = styled.li` color: ${props => (props.isClicked ? '#ff6a21' : '#bcbcbc')}; `;
++ 추가로 List에 있는 것들을 누를때 마다 해당 데이터에 맞는 페이지로 이동하기 (useNavigate 를 이용했다!)
//선언 const navigate = useNavigate(); const goToNav = item => { navigate(`${item.goTo}`); }; //FOOTER_LIST const FOOTER_LIST = [ { id: 1, title: '홈', defaultImg: './images/store.png', checkedImg: './images/storefront.png', goTo: '/', }, { id: 2, title: '자주가요', defaultImg: './images/favorite.png', checkedImg: './images/colorFavorite.png', goTo: '/favorite', }, { id: 3, title: '전단 등록', defaultImg: './images/upload.png', checkedImg: './images/colorUpload.png', goTo: '/upload', }, { id: 4, title: '마이페이지', defaultImg: './images/mypage.png', checkedImg: './images/colorMypage.png', goTo: '/Mypage', }, ];
이렇게 해 주고
<S.FooterList onClick={() => { handleClicked(index); goToNav(item); }} 해당 list에 있는 것을 눌렀을때 해당에 맞는 페이지로 이동할 수 있게 넣어주었다.
흙흙..
728x90'프론트앤드 > [React]' 카테고리의 다른 글
[React] 네이버 지도 API 이용 캐러셀 + center 움직이기 (0) 2023.03.31 [React] 네이버 지도 API 이용 + Slick 캐러셀 띄우기 (0) 2023.03.31 [React] 로그인 구현 + 비밀번호 보이게 기능 코드정리 (0) 2023.03.27 [React] 네이버 지도 API 이용 주소->좌표 구하기 (0) 2023.03.22 [React] KAKAO MAP API이용 (카카오맵) (0) 2023.03.08