티스토리 뷰
1. setInterval
0.) 목표
현재 가리키고 있는 slide 의 index 를 currIndex 라고 한다.
이때 currIndex 를 2초마다 +1 시키고, 그에 따라 pagination 의 색이 변하게끔 만드려고 한다.
1.) 문제점
setInterval(() => {
setCurrIndex((curr) => {
curr++;
if (curr > IMAGE_LENGTH) curr =1;
return curr;
})
}, 2000);
1-2-3-1-2-3 의 순서를 바랐는데... 예상과 달리 숫자가 이상하게 돈다.
2.) 문제 해결
state가 변함에 따라 setInterval도 함께 re-rendering이 되는 문제로,
useEffect()를 사용하여 해결했다.
컴포넌트가 마운트 됐을 때만 setInterval을 실행시켜줌에 따라,
컴포넌트가 리렌더링이 되어도 이전의 setInterval 현재의 함수에 영향을 미치지 않는다.
useEffect(() => {
const timer = setInterval(() => {
setCurrIndex((curr) => {
curr++;
if (curr > IMAGE_LENGTH) curr = 1;
return curr;
})
}, 2000);
}, [])
2. click으로 state 변경
0.) 목표
- click event로 navigation 을 가리키는 state를 변경하고자 한다.
1.) 문제점
- 클릭하면 2초간 기다린 뒤 다음 상태로 넘어가지 않고 클릭한 요소의 다음으로 바로 state가 넘어간다.
className={currIndex === 1 ? 'select' : ''}
리렌더링 문제인가? 하며 봤는데 click 이벤트가 발생하면 새로운 클래스가 지정되지조차 않는다.
state 변경은 잘 되는데 왜 안될까 싶어 코드를 다시 봤더니...
dataset에서 뽑는 index는 string 형식인데 엄격한 비교를 사용해서 클래스가 지정되지 않은 거였다... .
2.) 해결
일반 비교 구문으로 바꿔주거나
className={currIndex == 1 ? 'select' : ''}
dataset 값을 Number 형태로 바꿔준다.
const navOnClick = (e) => {
const {index} = e.target.dataset;
setCurrIndex((curr) => {
curr = Number(index);
return curr;
})
}
3. state 에 따른 list 변화
0.) 목표
- 현 상태 : currIndex 변수(state)에 따라 pagination 이 변하는 상태
- 목표: state 가 변경될 때 마다 transfrom - translateX 속성으로 li를 왼쪽으로 이동시켜 슬라이드를 완성시킨다.
? 다들 useRef 를 쓰라고 하는데 정확히 어떤 걸 하는 함수인지 잘 모르겠음...
1.) 문제
// * slide handler function
const slideHandler = (currIndex) => {
const slideWidth = document.querySelector('.slide').clientWidth;
const ul = document.querySelector('ul');
switch(currIndex) {
case 1:
ul.setAttribute('style', `left: ${0}px`)
break;
case 2:
ul.setAttribute('style', `left: ${-slideWidth}px`)
break;
case 3:
ul.setAttribute('style', `left: ${-slideWidth * 2}px`)
break;
default:
ul.setAttribute('style', `left: ${0}px`)
break;
}
}
useEffect(() => {
const timer = setInterval(() => {
setCurrIndex((curr) => {
curr++;
if (curr > IMAGE_LENGTH) curr = 1;
// slideHandler(curr);
return curr;
})
// * call slide handler
slideHandler(currIndex);
return () => clearInterval(timer);
}, 4000);
}, [])
- 4초마다 슬라이드를 변경해주어야 하기 때문에 slideHandler() 함수를 4초마다 호출해 currIndex에 따라 left 속성으로 방향을 이동시키려고 했다.
- 하지만 예상과 달리 슬라이드는 첫번째에서 멈춰 있고, slideHandler()함수로 넘어오는 값도 계속 1로만 찍혔다.
2.) 해결
// * change pagination status
useEffect(() => {
const timer = setInterval(() => {
setCurrIndex((curr) => {
curr++;
if (curr > IMAGE_LENGTH) curr = 1;
// * call slide handler
slideHandler(curr);
return curr;
})
return () => clearInterval(timer);
}, 4000);
}, [])
useEffect 내에서 setCurrIndex(setState함수)로 state가 변경된 이후 slideHandler를 실행시켜주었기 때문에 state의 변경이 적용되지 않았다.
따라서 setCurrIndex 함수 내에서 slideHandler를 호출하였다.
state 변경 - slideHandler - 다음 렌더링 전 의 로직으로 배치하면 slide처럼 동작한다.
'Web > React' 카테고리의 다른 글
[React] axios로 form 데이터 파일 전송 (0) | 2023.01.27 |
---|---|
[React] React예제 200 (78~84) - Redux (0) | 2022.06.24 |
[React] React 예제 200 - 76~77 (0) | 2022.06.24 |
[React, 프로젝트] 일치하는 목록 추천, 이메일 형식 검사 (0) | 2022.04.29 |
[React] 노마드코더 useState예제 (0) | 2022.04.25 |