1주차 분량의 함수형 코딩 책을 읽으면서 이 책은 개발자로서 코딩을 잘하는 방법? 다른 동료와 협업을 잘하는 방법? 효율적이고 효과적이고 드라마틱한 코딩 하는 법을 알려주는 책은 아니라고 느꼈다.
이 책은 개발자로서 서비스를 만들고 설계할 때 하나의 좋은 길을 제시해주는 책이라고 느꼈습니다. 또한 핵심은 각각의 함수는 독립적이어야 하고 (의존적이지 않고) 재사용 가능하다 라는게 핵심이다고 생각했습니다.
독립적이고 재사용 가능한 함수들을 조립하고 분해하는게 리액트의 컴포넌트들과 많이 닮아있다고 생각했음(이름도 함수형 컴포넌트임)
그래서 찾아보면 리액트에서 효과적이고 좋은 설계를 위한 몇가지 디자인 패턴이 존재하는데 오늘은 이것을 소개해보도록 하겠습니다.
합성 컴포넌트 패턴은 하나의 컴포넌트를 여러 가지 집합체로 분리한 뒤, 분리된 각 컴포넌트를 사용하는 쪽에서 조합해 사용하는 컴포넌트 패턴을 의미합니다.
<Dialog
dimmed
title="타이틀"
checkBoxList={[
{
title: '버튼명',
isChecked: true,
hasArrowButton: true,
},
{
title: '버튼명',
isChecked: false,
hasArrowButton: true,
},
{
title: '버튼명',
isChecked: false,
hasArrowButton: true,
},
{
title: '버튼명',
isChecked: false,
hasArrowButton: true,
},
{
title: '버튼명',
isChecked: false,
hasArrowButton: true,
},
]}
labelButtonList={[
{
title: '버튼레이블',
}
]}
/>
<Dialog>
<Dialog.Dimmed />
<Dialog.Title>타이틀</Dialog.Title>
<Dialog.CheckBox isChecked hasArrowButton>
버튼명
</Dialog.CheckBox>
<Dialog.CheckBox hasArrowButton>버튼명</Dialog.CheckBox>
<Dialog.CheckBox hasArrowButton>버튼명</Dialog.CheckBox>
{/* 혹시 여기에 무언가 설명이 들어가야 한다면 아래처럼 추가만 하면 됩니다. 더이상 이미 구현된 Dialog를 수정할 필요는 없습니다.
<Dialog.Description>설명</Dialog.Description>
*/}
<Dialog.CheckBox hasArrowButton>버튼명</Dialog.CheckBox>
<Dialog.CheckBox hasArrowButton>버튼명</Dialog.CheckBox>
<Dialog.LabelButton>버튼레이블</Dialog.LabelButton>
</Dialog>
export const Dialog = Object.assign(DialogMain, {
Dimmed: DialogDimmed,
Title: DialogTitle,
Subtitle: DialogSubtitle,
Description: DialogDescription,
Comment: DialogComment,
CheckButton: DialogCheckButton,
CheckBox: DialogCheckBox,
TextButton: DialogTextButton,
Button: DialogButton,
LabelButton: DialogLabelButton,
Divider: DialogDivider,
});
// Usage
<Dialog>
<Dialog.Title>제목</Dialog.Title>
</Dialog>
function SearchForm() {
const [searchKey, setSearcKey] = useState();
function onChange(event) {
setSearcKey(event.target.value);
}
function onSubmit(event) {
event.preventDefault();
console.log(searchKey);
}
return (
<form onSubmit={onSubmit}>
<div>
<label>제목</label>
<input type="text" value={searchKey} onChange={onChange} name="searchKey"/>
<button type="submit">검색</button>
</div>
</form>
)
}
export default SearchForm;
// Presentation Component
function SearchFormView() {
const {searchKey, onChange, onSubmit} = props;
return (
<form onSubmit={onSubmit}>
<div>
<label>제목</label>
<input type="text" value={searchKey} onChange={onChange} name="searchKey"/>
<button type="submit">검색</button>
</div>
</form>
)
}
export default SearchFormView;
// Container Component
function SearchFormContainer() {
const [searchKey, setSearcKey] = useState();
function onChange(event) {
setSearcKey(event.target.value);
}
function onSubmit(event) {
event.preventDefault();
console.log(searchKey);
}
return (
<SearchFormView
searchKey={searchKey}
onChange={onChange}
onSubmit={onSubmit}
/>
)
}
export default SearchFormContainer;
presentation 컴포넌트는 단순히 데이터, 상태 값만을 바라보고 어떤 기능을 하지 않는다 (데이터를 기반으로한 디자인만을 담당함)
Container 컴포넌트에서 여러가지 로직을 담당한다. 디자인은 전혀 담당하지 않는다.
책을 읽으면서도 나왔던 util 함수와도 비슷한 개념이지 않을까 싶습니다.!
// Hooks
export default function useSearch() {
const [searchKey, setSearcKey] = useState();
function onChange(event) {
setSearcKey(event.target.value);
}
function onSubmit(event) {
event.preventDefault();
console.log(searchKey);
}
return {
searchKey,
onChange,
onSubmit,
}
}
function SearchForm() {
const { searchKey, onChange, onSubmit } = useSearch();
return (
<form onSubmit={onSubmit}>
<div>
<label>제목</label>
<input type="text" value={searchKey} onChange={onChange} name="searchKey"/>
<button type="submit">검색</bu
tton>
</div>
</form>
)
}
export default SearchForm;