리팩토링한 컴포넌트 구조로 기존 코드를 수정했다.
ImageSlide
최상위 부모인 ImageSliderPage의 상태로 현재 슬라이드 index와 슬라이드의 갯수를 저장해주었다.
슬라이드, 넘김 버튼, 포인터 3가지의 컴포넌트를 만들어 ImageSliderPage의 해당 태그에 각각 연결해주었다.
setup() {
this.state = {
currentSlideIndex: 0,
maxLength: imageUrlList.length,
};
}
template() {
return `
<div id='Image-slider-container'>
<div data-component="slider"></div>
<div data-component="arrow-buttons"></div>
<div data-component="dots"></div>
</div>
`;
}
mounted() {
const $slider = this.$target.querySelector('[data-component="slider"]');
const $dots = this.$target.querySelector('[data-component="dots"]');
const $arrowButtons = this.$target.querySelector(
'[data-component="arrow-buttons"]',
);
this.Slider = new Slider($slider, {
currentSlideIndex: this.state.currentSlideIndex,
imageUrlList,
});
this.Dots = new Dots($dots, {
currentSlideIndex: this.state.currentSlideIndex,
indexArr: Array.from({ length: this.state.maxLength }, (_, i) => i),
});
new ArrowButtons($arrowButtons, {
onClickPrev: this.handleClickPrevButton.bind(this),
onClickNext: this.handleClickNextButton.bind(this),
});
}
넘김 버튼 click handler함수를 ArrowButtons컴포넌트의 props으로 전달해서 이벤트를 걸어줬다.
콜백함수에는 currentSlideIndex를 변경시켜주는 로직이 작성되어있다.
0에서부터 슬라이드 최대갯수-1의 범위까지 순환하도록 구현했다.
handleClickPrevButton() {
const { currentSlideIndex, maxLength } = this.state;
const newIndex =
currentSlideIndex === 0 ? maxLength - 1 : currentSlideIndex - 1;
this.setState({ ...this.state, currentSlideIndex: newIndex }, true);
}
handleClickNextButton() {
const { currentSlideIndex, maxLength } = this.state;
const newIndex =
currentSlideIndex === maxLength - 1 ? 0 : currentSlideIndex + 1;
this.setState({ ...this.state, currentSlideIndex: newIndex }, true);
}
넘김 버튼을 클릭해 ImageSliderPage의 상태인 currentSlideIndex가 변경되면 Slider와 Dots컴포넌트가 바뀐 상태로 다시 렌더링되게 구현했다.
화면 상 변하지 않는 ArrowButtons는 리렌더링되지 않게 했다.
reRender() {
this.Slider.setState({
...this.Slider.state,
currentSlideIndex: this.state.currentSlideIndex,
});
this.Dots.setState({
...this.Dots.state,
currentSlideIndex: this.state.currentSlideIndex,
});
}