위코드 1차 프로젝트에서 React - ClassComponent와 웹 퍼스트 방식만을 적용하여 만들었던 프로젝트를 React - Functal Component와 웹 퍼스트, 모바일 퍼스트 적용한 반응형으로 리팩토링 하였다.
프로젝트에서 화면 사이즈 변화할때 마다 resize
이벤트를 적용해서 브라우저 화면 크기가 바꿀 때 마다 그에 따라 유동적인 슬라이드 만들어야 했다. 그런 과정에서 브라우저의 사이즈 바뀔 때마다(리렌더)
함수를 다시 재생성하는게 불필요하여서 useCallback
를 사용했는데, 처음 접하는 사람들한테 직접 와닿지 않을 거 같아서 아래의 방법도 있다고 정리를 해보았다.
// Products.jsx
useEffect(() => {
const onWindowSize = () => {
setInnerWidth(window.innerWidth);
};
window.addEventListener('resize', onWindowSize);
return () => {
window.addEventListener('remove', onWindowSize);
};
}, []);
children은 부모의 레이아웃 그대로 이면서 자식 레이아웃만 바뀔 때 유용하다. 프로젝트 메인에서 슬라이드가 상단, 하단에 크기만 다른 슬라이드가 있었는데, children
을 사용해서 슬라이드의 큰 레이아웃은 그대로하고 버튼을 눌렀을 때만 안의 이미지 바꿔주면 되어서 매우 유용하게 사용했었다.
import React, { useState, useEffect } from 'react';
import Button from '../Button/Button';
import './Slide.scss';
function Slide({ title, list, name, children, onSlide }) {
const [slideBg, setSlideBg] = useState('');
const [slideCount, setSlideCount] = useState(1);
const handleNextClick = () => {
if (slideCount < list.length) {
setSlideCount(prev => prev + 1);
onSlide('next', slideCount);
}
};
const hadlePrevClick = () => {
if (slideCount > 1) {
setSlideCount(prev => prev - 1);
onSlide('prev', slideCount);
}
};
useEffect(() => {
let slideItem = list.find(item => item.id === slideCount);
setSlideBg(slideItem && slideItem.background);
}, [list, slideCount]);
if (list.length === 0) {
return null;
}
return (
<section className="slide" style={{ background: slideBg }}>
<div className={`slide-wrapper__${name}`}>
<h3 className={`slide-title__${name}`}>{title}</h3>
<ol className={`slide-count__list-${name}`}>
<li>
<Button
className="button--prev"
disabled={slideCount === 1}
onClick={hadlePrevClick}
>
<i className="fas fa-chevron-left" />
</Button>
</li>
<li className="start-count">
<span>{slideCount}</span>
</li>
<li className="center">
<span>/</span>
</li>
<li className="end-count">
<span>{list.length}</span>
</li>
<li>
<Button
className="button--next"
onClick={handleNextClick}
disabled={slideCount === list.length}
>
<i className="fas fa-chevron-right" />
</Button>
</li>
</ol>
</div>
{children}
</section>
);
}