카카오 프렌즈샵 클론 코딩 프로젝트를 진행하고 있다. 메인의 전체 제품보기 탭에서 두가지 방법으로 Sorting 하는 모달창을 작업하는 중 배운 "객체 계산된 속성명으로 중복된 함수를 축약한 방법"을 기록한다.
showOption = (e) => {
const { name } = e.target;
name === "sortByType"
? this.setState(
{
isTypeShown: !this.state.isTypeShown,
},
() => {
this.state.isTypeShown &&
this.setState({
isCharShown: false,
});
}
)
: this.setState(
{
isCharShown: !this.state.isCharShown,
},
() => {
this.state.isCharShown &&
this.setState({
isTypeShown: false,
});
}
);
};
제품 순서 모달과 캐릭터 필터링 모달에 토글되는 기능을 적용하고, 이미 A 창이 오픈되어있는 상태에서 다른 B 창을 클릭 시 A 창이 닫히는 기능까지 구현한 코드이다. 동일한 형태의 setState
함수가 반복되고 있고, 두번째 인자로 들어간 콜백함수까지 반복되어서 코드가 길어졌다.
위 코드를 객체 계산된 속성명으로 줄여보자!
class Sorting extends React.Component {
constructor() {
super();
this.state = {
charList: CHARACTER,
isTypeShown: false,
isCharShown: false,
};
}
// jsx
<button
className="sortingType sortBtn"
onClick={this.showOption}
value="isTypeShown"
>
판매량순
</button>
<button
className="sortingChar sortBtn"
onClick={this.showOption}
value="isCharShown"
>
캐릭터 전체
</button>
컴포넌트의 state와 동일한 이름의 value
값을 각 개체에게 부여해주었다.
showOption = (e) => {
const { value } = e.target;
this.setState({
isTypeShown: false,
isCharShown: false,
[value]: !this.state[value],
});
계산된 속성명인 [value]
값이 value
의 이름으로 동적으로 할당된다. 함수 구조는 동일하게 사용되고 객체만 달라지는 경우에는 꼭 계산된 속성명을 사용할 수 있는지 고민해보자!
다음에는 state의 isTypeShown
과 isCharShown
도 굳이 따로 state를 관리할 필요가 없어서 (한번에 하나의 모달창만 나올 수 있기 때문) 이를 Active Tab으로 고쳐보려고 한다.
메뉴 Active Tab에서 배웠던대로 하나의 변수를 가지고 두개의 모달창을 모두 관리할 수 있다.
예를 들어, 변수의 값이 0
일때는 두 모달 모두 보이지 않도록,
변수 값이 1
일 때는 모달 A가 나타나도록,
변수 값이 2
일 때는 모달 B가 나타나도록 하는 것이다.
whichModalShown
class Sorting extends React.Component {
constructor() {
super();
this.state = {
charList: CHARACTER,
whichModalShown: false,
};
}
showOption = (e) => {
const { whichModalShown } = this.state;
const { name } = e.target;
this.setState({
whichModalShown: whichModalShown !== name ? name : false
});
};
<button
className="sortingType sortBtn"
onClick={this.showOption}
name="typeModal"
>
판매량순
</button>
<div
className={`selectModalWrap selectType
${
whichModalShown === "typeModal"
? ""
: "hidden"
}
`}
>
<button
className="sortingChar sortBtn"
onClick={this.showOption}
name="charModal"
>
캐릭터 전체
</button>
<div
className={`selectModalWrap selectChar
${
whichModalShown === "charModal"
? ""
: "hidden"
}
`}
>