

์ต๊ทผ Nextjs๋ก ๋ง๋ ๋ธ๋ก๊ทธ๋ฅผ ๋ฆฌํฉํฐ๋งํ๋ฉด์ ๋ง์กฑ์ค๋ฝ์ง ์์ ๊ฒ ๊ฐ์ ๋ค์ ๋ฆฌํฉํฐ๋ง์ ๊ณต๋ถํด๋ณด๊ณ ์ ํ๋ค. ๋๋ "์ด๋ค ์์ธ๋ฅผ ์ทจํด์ผ ํ ๊น??" ํน์ "์ด๋ ์ ๋๊น์ง ๋ฆฌํฉํฐ๋ง ์์น์ ์ ์ฉํด์ผํ ๊น?" ํน์ "์ฑ ์์๋ ๋ฆฌํฉํฐ๋ง์ด ์ฑ๋ฅ์ ๋ฎ์ถ์ง๋ง ๋ฆฌํฉํฐ๋ง ํ์๋ ์คํ๋ ค ์ฑ๋ฅ ํ๋ํ๊ธฐ ํธํด์ง๋ค๋ ์์ผ๋ก ๋งํ์๋๋ฐ ๊ณผ์ฐ ๊ทธ๋ฐ ์ฌ์ ๋ฅผ ๊ฐ์ง๋ฉฐ ๋ฆฌํฉํฐ๋ง ํ ์ ์์๊น??"์ ๊ฐ์ ์๊ฐ์ ์์ฃผ ํ๋ค. ํ์ ์์๋ ์ํฉ์ ๋ฐ๋ผ ์ ์ ์ ์ด ๋ง์ด ๋ฌ๋ผ์ง๋ ๊ฒ ๊ฐ๋ค๋ ์๊ฐ์ ๋ง์ด ํ์๊ณ ๊ฒฐ๊ตญ ๋ชจ๋ ๊ฒ์ ํธ๋ ์ด๋์คํ ๊ด๊ณ๋ก ์ด๋ฃจ์ด์ง๋ค๋ ๊ฒ์ด ํ์ฌ ๋์ ์๊ฐ์ด๋ค... ์ด๋ฐ ๋ง์ฐํ ์๊ฐ ๋ง๊ณ ์ข ๋ ๊ตฌ์ฒด์ ์ผ๋ก ์ํฉ์ ๋ฐ๋ฅธ ํด๋ฒ์ ์ ์ํ ์ ์์ผ๋ฉด ์ข๊ฒ ๋ค.
๊ทธ๋์ ๋ด๊ฐ ๋ง๋ ์ปดํฌ๋ํธ ์ค ์๋ง์ธ ๋ถ๋ถ์ ๋ฆฌํฉํฐ๋ง ์ฑ ์ ๋์จ ๊ธฐ๋ณธ์ ์ธ ๋ฆฌํฉํฐ๋ง์ ์ ์ฉํ๋ฉด ์ด๋ป๊ฒ ๋๊ปด์ง์ง ์คํํด๋ณด๊ณ ์ ํ๋ค. ๋ฌผ๋ก ์๊ฐ์ด ๋ง์ด ๊ฑธ๋ ค์ ์ฑ ์ ์๋ ์์๋ ๋ง์ด ์ฌ์ฉํ ์์ ์ด๋ค.
ํจ์ ํธ์ถํ๊ธฐ๋ ์ธ๋ผ์ธ ์ฝ๋๋ฅผ ๋ณ๋๋ก ํจ์๋ก ๋ง๋ค์ด ํธ์ถํ๋ ๊ฒ์ ์๋ฏธํ๋ค. ํจ์(function) ์ถ์ถํ๊ธฐ์์ ํจ์๋ ๊ฐ์ฒด ์งํฅ ์ธ์ด์ ๋ฉ์๋(method)๋ ์ ์ฐจํ ์ธ์ด์ ํ๋ก์์ (procedure)๋ ์๋ธ๋ฃจํด(subroutine)์ด๋ผ๊ณ ๋ณด๊ณ ๋๊ฐ์ด ์ ์ฉํ๋ฉด ๋๋ค.
์ฝ๋๋ฅผ "์ธ์ ํจ์๋ก ๋ฌถ์ด์ผ ํ ๊น?"๋ผ๋ ๊ธฐ์ค์ ๋๋ ๋๋ ๋ค๋ฅด๋ค. ๊ทธ ๊ธฐ์ค์ ๊ธธ์ด๊ฐ ๋ ์ ์๊ณ , ํ๋ฉด์ ๊ธฐ์ค์ผ๋ก ๋ ์ ์๊ณ , ์ฌ์ฌ์ฉ์ฑ์ ๊ธฐ์ค์ผ๋ก ๋ ์ ์๋ค. ๋ฆฌํฉํฐ๋ง ์ฑ ์ ์๋ "๋ชฉ์ ๊ณผ ๊ตฌํ์ ๋ถ๋ฆฌ"ํ๋ ๋ฐฉ์์ด ๊ฐ์ฅ ํฉ๋ฆฌ์ ์ธ ๊ธฐ์ค์ผ๋ก ๋ณธ๋ค. ๊ฐ์ธ ์ ์ธ ํด์์ผ๋ก๋ ์ถ์ํ๋ผ๊ณ ์๊ฐํ๋ค. ๊ตฌํํ ์ฝ๋์ ์๋ฏธ(๋ชฉ์ )์ ํ๋์ ๋ค์ด๋ฐ(ํจ์)๋ก ์ถ์ํํ์ฌ ๋ถ๋ฆฌํ๋ ๊ฒ์ด๋ผ๋ ์๋ฆฌ๋ก ํด์๋๋ค.(๋์!!)
์ ์๊ฐ ์๋ฅผ ๋ ๊ฒ ์ค ํ๋๊ฐ. highlight๋ผ๋ ํจ์๊ฐ ์๋๋ฐ ์ด ํจ์๋ reverse()๋ฅผ ํธ์ถํ์ฌ ์์์ ๋ฐ์ ๋ง ํ๋ ์ฝ๋ 1๊ฐ๋ง ์์๋ค๊ณ ํ๋ค. hilight(๊ฐ์กฐ)๊ฐ ๋ชฉ์ ์ด๋ฉฐ ๊ทธ ๋ชฉ์ ์ ๋ฌ์ฑํ๊ธฐ ์ํ ๊ตฌํ์ reverse(์์ ๋ฐ์ )์ด ๋๋ค๋ ๊ฒ์ด๋ค.
๋ํ ์ ์๋ ํจ์๋ฅผ ์งง๊ฒ ๋ง๋ค๋ฉด ํจ์ ํธ์ถ์ด ๋ง์์ ธ์ ์ฑ๋ฅ์ด ๋๋ ค์ง๊น๋ด ๊ฑฑ์ ํ๋ ์ฌ๋์ด ์๋ค๊ณ ํ๋๋ฐ, ํจ์๊ฐ ์งง์ผ๋ฉด ์บ์ฑํ๊ธฐ๊ฐ ๋ ์ฝ๊ธฐ ๋๋ฌธ์ ์ปดํ์ผ๋ฌ๊ฐ ์ต์ ํํ๋ ๋ฐ ์ ๋ฆฌํ ๋๊ฐ ๋ง๋ค๊ณ ํ๋ค. ๊ทผ๋ฐ ๊ฐ์ธ์ ์ธ ๊ฒฝํ์ผ๋ก๋ ๊ทธ๋ ์ง ์์๋ ๊ฒฝ์ฐ๊ฐ ์์ด์ ๋๋ ๋์ํ๊ธฐ๊ฐ ํ๋ค์๋ค. ๋์ฉ๋ ๋ฆฌ์คํธ๋ฅผ ์์ ํ์์ผ๋ก ๊ด๋ฆฌํ๋ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ ์ ์ด ์์๋๋ฐ, ๋ฆฌ์คํธ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ ๋ for๋ฌธ์ ์ฌ์ฉํ๋ ๊ฒ๊ณผ Array.forEach๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ๋ฌด์ํ์ง ๋ชปํ ์ ๋์ ์๋๊ฐ ์ฐจ์ด๋๋ ๊ฒฝํํ์๊ธฐ ๋๋ฌธ์ด๋ค. ์ค์ ์ฌ์ฉํ์๋ ๋ฏธ์ธํ ๋ ??๋ ์ค์ด๋ค์์๋ค. ๊ทธ ์์ธ์ ์๋ฐ์คํฌ๋ฆฝํธ ์คํ ์ปจํ ์คํธ ์์ฑ์ ๋ฌด๋ผ๊ณ ์๊ฐํ์๊ธด ํ๋ค.
๋ค์์ ์ ์๊ฐ ๋งํ๋ ํจ์ ์ถ์ถ ์ ์ฐจ์ด๋ค
์ ์ฐจ
ํจ์๋ฅผ ์๋ก ๋ง๋ค๊ณ ๋ชฉ์ ์ ์ ๋๋ฌ๋ด๋ ์ด๋ฆ ๋ถ์ด๊ธฐ("์ด๋ป๊ฒ"๊ฐ ์๋๋ผ "๋ฌด์์" ํ๋์ง ์ ๋ํ๋ด์ผํจ)
์ถ์ถํ ์ฝ๋๋ฅผ ๋ณต์ฌํ์ฌ ์ ํจ์์ ๋ถ์ด๊ธฐ.
์ถ์ถํ ์ฝ๋์์ ์๋ณธ ํจ์์ ์ง์ญ ๋ณ์๋ฅผ ์ฐธ์กฐํ๊ฑฐ๋ ์ถ์ถํ ํจ์์ ์ ํจ๋ฒ์๋ฅผ ๋ฒ์ด๋๋ ๋ณ์๋ ๋งค๊ฐ๋ณ์(ํ๋ผ๋ฏธํฐ)๋ก ์ ๋ฌ.(๋จ ํจ์ ์์ ์ค์ฒฉ ํจ์๋ก ์ ์ธ ๊ฐ๋ฅํ ๊ฒฝ์ฐ์๋ ์ง์ญ ๋ณ์๋ฅผ ๋งค๊ฐ๋ณ์๋ก ๋ฐ์ง ์์ ์ ์์.)
ํจ์ ์ปดํ์ผ ํด๋ณด๊ธฐ
์๋ณธ ํจ์์ ์ฝ๋๋ฅผ ์๋ก ๋ง๋ ํจ์๋ก ๊ต์ฒด
ํ ์คํธ
๋ค๋ฅธ ์ฝ๋์ ์ถ์ถํ ํจ์์ ๋น์ทํ ์ฝ๋๊ฐ ์๋์ง ํ์ธํ ํ, ์ถ์ถํ ํจ์๋ก ๋ฐ๊ฟ์ง ๊ฒฐ์ .
๊ทธ๋ฆฌ๊ณ ์๋๋ ๋ด๊ฐ ๋ง๋ค์ด๋ณธ ๊ฐ๋จํ ์ ์ฐจ์ด๋ค
์ ์ฐจ2 (๋ด๊ฐ ๋ง๋ค์ด๋ณธ ๊ฐ์ํํ ์ ์ฐจ)
์ธ๋ผ์ธ ์ฝ๋๋ค์ ์ฃผ์์ผ๋ก ๋ฌด์จ ์ผ์ ํ๋์ง ๋ฌถ์ด์ ์ ์ด๋ณธ๋ค.
์ฃผ์์ ํตํด ๋ชฉ์ ์ ๋ง๋ ํจ์๋ช ์ผ๋ก ํจ์๋ฅผ ์ถ์ถํ๋ค.
์ถ์ถํ ํจ์๋ก ์ธ๋ผ์ธ ์ฝ๋๋ฅผ ๊ต์ฒดํ๋ค.
๋ค์ ๋ฒ์ ๋น์ทํ ๋ก์ง์ด ์ฌ์ฉ๋๋ ๊ฒ์ ๋ฐ๊ฒฌํ๋ฉด ํจ์๋ฅผ ๊ณตํต์ผ๋ก ๋บ์ง ๊ณ ๋ คํด๋ณธ๋ค.
์๋๋ ํจ์ ์ถ์ถ ์ ์ฉ ์ ๊ณผ ํ ์์์ ๋๋ค. ์ ๋ณ๋ hook์ผ๋ก ๋ถ๋ฆฌ ์ํ๋๊ณ ๋ฌผ์ผ์ ๋ค๋ฉด.. ํ๊ฒ ์ต๋๋ค ใ ใ
const SidebarProfile = () => { const {name, role, profileImg, isLogined, changeName, logout} = useAuth(); // name edit ๊ด๋ จ ๋ณ์๋ค const [isNameValid, setIsNameValid] = useState<boolean>(true); const [isEdit, setIsEdit] = useState<boolean>(false); const nameInputRef = useRef<HTMLInputElement>(null); // ๋น๋ก๊ทธ์ธ ์ ์ถ๋ ฅ X; if (!isLogined) return; // ์ด๋๋ฏผ ์ฌ๋ถ const isAdmin = role === "ADMIN"; return ( <> <div style={{ display: "flex", flexDirection: "row", flexGrow: 1, alignItems: "center", gap: "0.75rem", paddingInline: "1.25rem", }}> <div className="border-1 h-8 overflow-hidden rounded-full" style={{position: "relative"}}> <Image src={`${FILE_SERVER_URL}/${profileImg}`} alt="profile image" width={32} height={32} unoptimized={true} /> </div> <div style={{ display: "flex", flexDirection: "row", justifyContent: "space-between", alignItems: "center", gap: "0.375rem", flexGrow: 1, }}> {isEdit ? ( <TextField id="name-change" className={`max-w-23`} size="sm" hasError={!isNameValid} defaultValue={name || "์ต๋ช
"} placeholder="2-20 ๊ธ์" // ์ด ์ด๋ฆ ์์ input ์ถ๋ ฅ์ focus ํด์ฃผ๊ธฐ๊ธฐ ref={node => { if (node) { nameInputRef.current = node; node.focus(); } }} // ์ด๋ฆ ์ ํจ์ฑ ์ฌ๋ถ๋ถ onChange={e => { const newName = e.currentTarget.value; if (newName.length < 2 || newName.length>=10) { setIsNameValid(false); } else { setIsNameValid(true); } }} /> ) : ( <span>{name}</span> )} <div style={{ display: "flex", flexDirection: "row", gap: "0.375rem", }}> {isEdit ? ( <IconButton icon="check" size="md" onClick={() => { // ์ด๋ฆ ์์ ์๋๋ const newName = (nameInputRef.current?.value)?.trim() || ""; if (newName && name) { if (newName === name) { setIsNameValid(false); return; } patchUser({ originName: name, willChangeName: newName, }).then(newName => { changeName(newName); setIsEdit(false); }); } else { setIsNameValid(false); } }} /> ) : null} <IconButton aria-label="name-edit" icon={isEdit ? "x" : "edit"} size="md" tooltip={isEdit ? "์์ ์ทจ์" : "๋๋ค์ ์์ "} // ์์ ์ ์ทจ์ํ๊ฑฐ ์์ ๋ชจ๋๋ก ์ง์
ํ ๊ธ๊ธ onClick={() => { setIsNameValid(true); setIsEdit(prev => !prev); }} /> </div> </div> </div> <Card className="mx-5 flex flex-row justify-between px-2 py-1"> <IconButton as={Link} prefetch={false} href={"/article/create"} variant="secondary" disabled={!isAdmin} aria-label="go to write article" tooltip="๊ธ์ฐ๊ธฐ" icon="writing" size="lg" /> <IconButton as={Link} prefetch={false} variant="secondary" tooltip="์นดํ
๊ณ ๋ฆฌ ํธ์ง" aria-label="go to edit category" disabled={!isAdmin} href={"/category/edit"} icon="category" size="lg" /> <form method="POST" action={`${BACK_SERVER_URL}/auth/logout`}> <IconButton icon="logout" type="submit" name="logout" id="logout" variant="secondary" size="lg" tooltip="๋ก๊ทธ์์" aria-label="logout" // ๋ก๊ทธ์์ ๋ฐ, app์ ์ํ ์ด๋ฒคํธ ์ ๋ฌ. onClick={() => { logout(); if (window.ReactNativeWebView) window.ReactNativeWebView.postMessage("googleSignOut"); }} /> </form> </Card> </> );};export default SidebarProfile;const SidebarProfile = () => { const {name, role, profileImg, isLogined, changeName, logout} = useAuth(); const [isNameValid, setIsNameValid] = useState<boolean>(true); const [isEdit, setIsEdit] = useState<boolean>(false); const nameInputRef = useRef<HTMLInputElement>(null); const validateName = useCallback( (newName: string | null): newName is string => { const isValidName = !!newName && 2 <= newName.length && newName.length < 10 && newName !== name; return isValidName; }, [name], ); const toggleDisplayNameInput = useCallback(() => { setIsNameValid(true); setIsEdit(prev => !prev); }, []); const fetchChangeName = useCallback( (newName: string) => { const isValidName = validateName(newName); if (!isValidName) return setIsNameValid(false); function handleNameChangeSuccess(name: string) { changeName(name); toggleDisplayNameInput(); } patchUser({ originName: name!, willChangeName: newName, }).then(newName => { handleNameChangeSuccess(newName); }); }, [name, changeName, toggleDisplayNameInput, validateName], ); // ๋น๋ก๊ทธ์ธ ์ ์ถ๋ ฅ X; if (!isLogined) return; // ์ด๋๋ฏผ ์ฌ๋ถ const isAdmin = role === "ADMIN"; return ( <> <div style={{ display: "flex", flexDirection: "row", flexGrow: 1, alignItems: "center", gap: "0.75rem", paddingInline: "1.25rem", }}> <div className="border-1 h-8 overflow-hidden rounded-full" style={{position: "relative"}}> <Image src={`${FILE_SERVER_URL}/${profileImg}`} alt="profile image" width={32} height={32} unoptimized={true} /> </div> <div style={{ display: "flex", flexDirection: "row", justifyContent: "space-between", alignItems: "center", gap: "0.375rem", flexGrow: 1, }}> {isEdit ? ( <TextField id="name-change" className={`max-w-23`} size="sm" hasError={!isNameValid} defaultValue={name || "์ต๋ช
"} placeholder="2-20 ๊ธ์" // ์ด ์ด๋ฆ ์์ input ์ถ๋ ฅ์ focus ํด์ฃผ๊ธฐ๊ธฐ ref={node => { nameInputRef.current = node; node?.focus(); }} // ์ด๋ฆ ์ ํจ์ฑ ์ฌ๋ถ๋ถ onChange={e => { const newName = e.currentTarget.value; const isValidName = validateName(newName); setIsNameValid(isValidName); }} /> ) : ( <span>{name}</span> )} <div style={{ display: "flex", flexDirection: "row", gap: "0.375rem", }}> {isEdit && ( <IconButton icon="check" size="md" disabled={!isNameValid} onClick={() => { // ์ด๋ฆ ์์ ์๋๋ const newName = getTrimmedName(nameInputRef.current?.value); fetchChangeName(newName); }} /> )} <IconButton aria-label="name-edit" icon={isEdit ? "x" : "edit"} size="md" tooltip={isEdit ? "์์ ์ทจ์" : "๋๋ค์ ์์ "} // ์์ ์ ์ทจ์ํ๊ฑฐ ์์ ๋ชจ๋๋ก ์ง์
ํ ๊ธ๊ธ onClick={toggleDisplayNameInput} /> </div> </div> </div> <Card className="mx-5 flex flex-row justify-between px-2 py-1"> <IconButton as={Link} prefetch={false} href={"/article/create"} variant="secondary" disabled={!isAdmin} aria-label="go to write article" tooltip="๊ธ์ฐ๊ธฐ" icon="writing" size="lg" /> <IconButton as={Link} prefetch={false} variant="secondary" tooltip="์นดํ
๊ณ ๋ฆฌ ํธ์ง" aria-label="go to edit category" disabled={!isAdmin} href={"/category/edit"} icon="category" size="lg" /> <form method="POST" action={`${BACK_SERVER_URL}/auth/logout`}> <IconButton icon="logout" type="submit" name="logout" id="logout" variant="secondary" size="lg" tooltip="๋ก๊ทธ์์" aria-label="logout" // ๋ก๊ทธ์์ ๋ฐ, app์ ์ํ ์ด๋ฒคํธ ์ ๋ฌ. onClick={logout} /> </form> </Card> </> );};export default SidebarProfile;function getTrimmedName(name?: string | null) { return name?.trim() || "";}ํจ์ ์ธ๋ผ์ธํ๊ธฐ๋ ํจ์ ํธ์ถํ๊ธฐ์ ๋ฐ๋๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ค. ํจ์๋ก ๋ฐ๋ก ๋บ ์ฝ๋๋ฅผ ํจ์๋ฅผ ์ ๊ฑฐํ๊ณ ์ฝ๋๋ฅผ ์ง์ ์ฌ์ฉํ๋ ๊ฒ์ด๋ค.
ํจ์ ๋ณธ๋ฌธ(์ธ๋ผ์ธ ์ฝ๋)๊ฐ "๊ตณ์ด ๋ฐ๋ก ํจ์๋ก ์ถ์ถํ์ง ์์๋ ๋ ๋งํผ ๋ช ํํ ๊ฒฝ์ฐ" ํน์ "ํจ์ ์ด๋ฆ๋งํผ ๊น๋ํ๊ฒ ๋ฆฌํฉํฐ๋งํ ์ฝ๋์ธ ๊ฒฝ์ฐ"์ ํจ์๋ฅผ ์ ๊ฑฐํ๊ณ ์ฝ๋ ์ธ๋ผ์ธ์ ๊ทธ๋๋ก ์ฌ์ฉํ๋ค. ์ฆ ๊ตณ์ด ๋ถ๋ฆฌํ์ง ์์๋ ๋ ๋งํผ ๋ช ํํ๊ฑฐ๋, ๋ฆฌํฉํฐ๋ง์ ์๋ชปํ์ฌ ์๋ชป ํจ์๋ฅผ ์ถ์ถ์ ํ ๊ฒฝ์ฐ์ ํจ์ ์ธ๋ผ์ธ์ ์ ์ฉํ๋ค๊ณ ๋ณด๋ฉด ๋๋ค. ๋ํ ๊ฐ์ ํธ์ถ์ ๋๋ฌด ๊ณผํ๊ฒ ์ฐ๋ ์ฝ๋๋ ์ธ๋ผ์ธ ๋์์ด๋ผ๊ณ ์ ์๊ฐ ๋งํ๋ค. ๋จ์ํ ์์ํ๊ธฐ ์ํ ํจ์๊ฐ ๋ง์์ ์์ ๊ด๊ณ๊ฐ ๋ณต์กํ๊ฒ ์ฝํ ์์ผ๋ฉด ์ธ๋ผ์ธํด๋ฒ๋ฆฐ๋ค.
๋ง๋ก๋ ๊ฐ๋จํด ๋ณด์ฌ๋ ์ค์ ๋ก๋ ๊ทธ๋ ์ง ์๋ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค. ์๋ฅผ ๋ค๋ฉด ์ฌ๊ท ํธ์ถ, ๋ฐํ๋ฌธ์ด ์ฌ๋ฌ๊ฐ์ธ ํจ์, ์ ๊ทผ์๊ฐ ์๋ ๋ค๋ฅธ ๊ฐ์ฒด์ ๋ฉ์๋๋ฅผ ์ธ๋ผ์ธํ๋ ๋ฐฉ๋ฒ ๋ฑ๋ฑ ์ค์ ๋ก๋ ์ธ๋ผ์ธํ๊ธฐ ์ด๋ ค์ด ๊ฒฝ์ฐ๊ฐ ๋ง๋ค๊ณ ํ๋ค. ๊ทธ๋ฐ๋ฐ ๋ณดํต ์ด๋ฐ ๊ฒฝ์ฐ์๋ ์ธ๋ผ์ธ์ ์ ์ฉํ๋ฉด ์๋๋ ๊ฒฝ์ฐ์ผ ๊ฒ์ด๋ผ๊ณ ์ ์๊ฐ ์ค๋ช ํ๋ค.
๋ค์์ ์ ์๊ฐ ๋งํ๋ ์ ์ฐจ๋ค
์ ์ฐจ
๋คํ ๋ฉ์๋์ธ์ง ํ์ธํ๋ค. (์๋ธํด๋์ค์์ ์ค๋ฒ๋ผ์ด๋ํ๋ ๋ฉ์๋๋ ์ธ๋ผ์ธํ๋ฉด ์ ๋๋ค.)
์ธ๋ผ์ธํ ํจ์๋ฅผ ํธ์ถํ๋ ๊ณณ์ ๋ชจ๋ ์ฐพ๋๋ค.
๊ฐ ํธ์ถ๋ฌธ์ ํจ์ ๋ณธ๋ฌธ์ผ๋ก ๊ต์ฒดํ๋ค.
ํ๋์ฉ ๊ต์ฒดํ ๋๋ง๋ค ํ ์คํธํ๋ค. (๊ตณ์ด ํ๋ฒ์ ์ฒ๋ฆฌํ ํ์ ์๊ณ ๊น๋ค๋ก์ด ๋ถ๋ถ์ ์ผ๋จ ๋จ๊ธฐ๊ณ ์ฌ์ ๊ฐ ์๊ธฐ๋ฉด ํํ์ด ํ๋ค.)
ํจ์ ์ ์๋ฅผ ์ญ์ ํ๋ค.
์๋ ์์๋ ์ฑ ์ ๋์จ ๊ฐ๋จํ ์์๋ค.
function rating(aDriver) { return moreThanFivelateDeliveries(aDriver) ? 2 : 1;}function moreThanFiveLateDeliveries(dvr) { return dvr.numberOfLateDeliveries > 5;}function rating(aDriver) { return aDriver.numberOfLateDeliveries > 5;}ํํ์์ด ๋๋ฌด ๋ณต์กํด์ ์ดํดํ๊ธฐ ์ด๋ ค์ธ ๋๊ฐ ์๋ค. ์ด๋ด ๋ ์ง์ญ๋ณ์๋ฅผ ํ์ฉํ๋ฉด ํํ์์ ์ชผ๊ฐ ๊ด๋ฆฌํ๊ธฐ ๋ ์ฝ๊ฒ ๋ง๋ค ์ ์๋ค.(๊ฐ๋ ์ฑ์ ๋ค)
๊ทธ๋ฌ๋ฉด ๋ณต์กํ ๋ก์ง์ ๊ตฌ์ฑํ๋ ๋จ๊ณ๋ง๋ค ์ด๋ฆ์ ๋ถ์ผ ์ ์์ด ์ฝ๋์ ๋ชฉ์ ์ ํจ์ฌ ๋ช ํํ๊ฒ ๋๋ฌ๋ผ ์ ์๋ค.
๋ํ ์ถ๊ฐํ ๋ณ์๋ ๋๋ฒ๊น ์๋ ๋์๋๋ค. ๋๋ฒ๊ฑฐ์ ์ค๋จ์ ์ ์ง์ ํ๊ฑฐ๋ ์ํ๋ฅผ ์ถ๋ ฅํ๊ฒํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
๋ณ์๋ก ์ถ์ถํ ๋์๋ ์ด๋ฆ์ด ๋ค์ด๊ฐ ๋ฌธ๋งฅ์ ๊ณ ๋ คํด์ผํ๋ค. ํ์ฌ ํจ์ ์์์๋ง ์๋ฏธ๊ฐ ์๋ ์ด๋ฆ์ผ๋ก ๋ค์ด๊ฐ ์๋ ์์ง๋ง, ๋ ๋์ ๋ฌธ๋งฅ์์ ์ฌ์ฉํ๋ค๋ฉด ๊ทธ์ ์๋ง๋ ์ด๋ฆ์ ๋ณ์๋ก ์ถ์ถํด์ ์ค๋ณต์ด ์ ์ ์ฝ๋๋ฅผ ์์ฑํด์ผํ๋ค. ๊ทธ๋ฐ๋ฐ ๋์ ๋ฌธ๋งฅ๊น์ง ๋ํ๋ค๋ฉด ์ฃผ๋ก ํจ์๋ก ์ถ์ถ๋๋ค.(ex. getBasePrice())
์๋๋ ๋ฆฌํฉํฐ๋ง ์ ์์ ์ ์ฐจ์ด๋ค.
์ ์ฐจ
์ถ์ถํ๋ ค๋ ํํ์์ ๋ถ์์ฉ์ ์๋์ง ํ์ธํ๋ค.
๋ถ๋ณ ๋ณ์๋ฅผ ํ๋ ์ ์ธํ๊ณ ์ด๋ฆ์ ๋ถ์ผ ํํ์์ ๋ณต์ ๋ณธ์ ๋์ ํ๋ค.
์๋ณธ ํํ์์ ์๋ก ๋ง๋ ๋ณ์๋ก ๊ต์ฒดํ๋ค.
ํ ์คํธํ๋ค.
ํํ์์ ์ฌ๋ฌ๊ณณ์์ ์ฌ์ฉํ๋ค๋ฉด ๊ฐ๊ฐ์ ์๋ก ๋ง๋ ๋ณ์๋ก ๊ต์ฒดํ๋ค. ํ๋ ๊ต์ฒดํ ๋๋ง๋ค ํ ์คํธํ๋ค.
์ฌ๊ธฐ์๋ ์ ์์ ์์์ ์ ์ ์์๋ฅผ ํจ๊ป ๊ณต์ ํ๊ฒ ์ต๋๋ค.
function price(order) { // ๊ฐ๊ฒฉ(price) = ๊ธฐ๋ณธ ๊ฐ๊ฒฉ - ์๋ ํ ์ธ + ๋ฐฐ์ก๋น return order.quantity * order.itemPrice - Math.max(0, order.quantity - 500) * order.itemPrice*0.05 + Math.min(order.quantity * order.itemPrice*0.1,100);}function price(order) { const basePrice = order.quantity * order.itemPrice; const quantityDiscount = Math.max(0, order.quantity - 500) * order.itemPrice*0.05; const shipping = Math.min(order.quantity * order.itemPrice*0.1,100); return basePrice - quantityDiscount + shipping;}class Order { get quantity() {return this._data.quantity;} get itemPrice() {return this._data.itemPrice;} get basePrice() {return this.quantity + this.itemPrice;} get quantityDiscount() {return Math.max(0, this.quantity - 500) * this.itemPrice*0.05;} get shipping() {return Math.min(this.quantity * this.itemPrice*0.1,100);} get price() { return this.basePrice - this.quantityDiscount + this.shipping; }} const NAME_MAX_LENGTH = 10;const NAME_MIN_LENGTH = 2;const validateName = useCallback( (newName: string | null): newName is string => { const isValidName = !!newName && NAME_MIN_LENGTH <= newName.length && newName.length < NAME_MAX_LENGTH && newName !== name; return isValidName; }, [name]);์ ์์ ์์๋ฅผ ๋ณด๋ฉด. class ํํ์์ get ์ผ๋ก ์ฐ์ฐํด์ ๊ฐ์ ๊ฐ์ ธ์จ๋ค. ์ด๊ฒ ์ค์ํ ์ ์ side effect๊ฐ ์๋ค๋ ์ ์ด๋ค(์ ์ฐจ์ 1๋ฒ์ ์ค์ํจ). ์๋ํ๋ฉด ๋ณ๋์ set์ ํ์ง ์๊ณ get์ผ๋ก ๊ณ์ฐํ์ฌ ๊ฐ์ ธ์ค๊ธฐ ๋๋ฌธ์ด๋ค.
๋ณ์ ์ธ๋ผ์ธํ๊ธฐ๋ ๋๋ฌด ๊ฐ๋จํด์ ์์๋ก ์ค๋ช ํ๊ฒ ๋ค. ํ์ค ์์ฝ ํ๋ฉด ์๋ ํํ์๊ณผ ๋ค๋ฅผ ๋ฐ ์์ ์ ๋๋ก ์๋ฏธ๊ฐ ์๊ฑฐ๋ ๋ฆฌํฉํฐ๋ง ํ๋๋ฐ ์คํ๋ ค ๋ฐฉํด๊ฐ ๋ ๋ ์ธ๋ผ์ธ ํ๋ค.
// ------------- ์ธ๋ผ์ธ ์ ------------- //let basePrice = anOrder.basePrice;return (basePrice > 1000);// ------------- ์ธ๋ผ์ธ ํ ------------- //return anOrder.basePrice > 1000;๊ทธ๋๋ ์ฃผ์ํ ์ ์ ๋์ ๋ฌธ์ ์ฐ๋ณ(ํํ์)์์ ๋ถ์์ฉ์ด ์๊ธฐ์ง ์๋์ง ํ์ธํด์ผ ํ๋ค.
์ ์๋ ํจ์๋ ํ๋ก๊ทธ๋จ์ ๋๋๋ ์ฃผ๋ ์๋จ์ด๋ผ๊ณ ํ๋ค. ํจ์ ์ ์ธ์ ๊ฐ ๋ถ๋ถ์ด ์๋ก ๋ง๋ฌผ๋ฆฌ๋ ๋ฐฉ์์ ํํํ๋ฉฐ ์ํํธ์จ์ด ์์คํ ์ ๊ตฌ์ฑ ์์๋ฅผ ์กฐ๋ฆฝํ๋ ์ฐ๊ฒฐ๋ถ ์ญํ ์ ํ๋ค. ๊ทธ๋์ ์ฐ๊ฒฐ๋ถ๋ฅผ ์ ์ ์ํ๋ฉด ์์คํ ์ ์๋ก์ด ๋ถ๋ถ์ ์ถ๊ฐํ๊ธฐ ์ฌ์์ง์ง๋ง, ์๋ชป ์ ์ํ๋ฉด ์ง์์ ์ธ ๋ฐฉํด ์์ธ์ด ๋๋ค.
์ด๋ฌํ ์ฐ๊ฒฐ๋ถ์์ ๊ฐ์ฅ ์ค์ํ ์์๋ ํจ์์ ์ด๋ฆ์ด๋ค. ์ด๋ฆ์ด ์ข์ผ๋ฉด ํจ์์ ๊ตฌํ ์ฝ๋๋ฅผ ๋ณผ ํ์ ์์ด ํธ์ถ๋ฌธ๋ง ๋ณด๊ณ ๋ ๋ฌด์จ ์ผ์ ํ๋์ง ํ์ ํ ์ ์๋ค. ํ์ง๋ง ์ข์ ์ด๋ฆ์ ๋ ์ฌ๋ฆฌ๊ธฐ ํ๋ค๋ฉฐ, ์ธ์ ๋ ์์ข์ ์ด๋ฆ์ ๊ทธ๋๋ก ๋๋๊ณ ์ถ์ ์ ํน์ ๋น ์ง๋ค!!!! ์ข์ ์ด๋ฆ์ด ์๊ฐ๋๋ฉด ๋ฐ๋ก๋ฐ๋ก ๋ฐ์ํ๋ ๋ฒ๋ฆ์ ๊ฐ์ง์.
๊ทธ๋ฌ๋ฉด ์ข์ ์ด๋ฆ์ ์ด๋ป๊ฒ ์ ๋ ์ฌ๋ฆด๊น?? ๋ฐ๋ก ํจ์์ ๋ชฉ์ ์ ์ค๋ช ํ๋ ๊ฒ์ด๋ค. ์ฃผ์์ผ๋ก ๋ชฉ์ ์ ์ ์ํด๋ณด๊ณ ์ฃผ์์ ์ง์ ์ข์ ์ด๋ฆ์ผ๋ก ๋ฐ๊ฟ ๊ปด๋ณด์.(์ฃผ์์ด ํ์์๋ ๋ค์ด๋ฐ์ ํด๋ณด์)
ํจ์์ ๋งค๊ฐ๋ณ์๋ ๋ง์ฐฌ๊ฐ์ง๋ค. ๋งค๊ฐ๋ณ์๋ ํจ์๊ฐ ์ธ๋ถ ์ธ๊ณ์ ์ด์ฐ๋ฌ์ง๋ ๋ฐฉ์์ ์ ์ํ๋ ๊ฒ์ด๋ค. ๋งค๊ฐ๋ณ์๋ ํจ์๋ฅผ ์ฌ์ฉํ๋ ๋ฌธ๋งฅ์ ๊ฒฐ์ ํ๋ค. ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ์ ํํ๊ธฐ๋ ๋จ์ํ ๊ท์น์ผ๋ก ํํํ ์ ์๊ณ ์ ๋ต์ด ์๋ค. ์๋ฅผ ๋ค๋ฉด ์ด๋ค ๊ฐ์ฒด์ ๋์ฌ ๊ธฐ๊ฐ์ด 30์ผ ์ง๋ฌ๋์ง ๊ธฐ์ค์ผ๋ก ์ง๋ถ ๊ธฐํ์ด ๋์๋์ง ํ๋จํ๋ ๊ฐ๋จํ ํจ์๊ฐ ์๋ค๊ณ ํ ๋, ๊ฐ์ฒด๋ฅผ ๋งค๊ฐ๋ณ์๋ก ํ ์ง, ์ง๋ถ ๊ธฐํ์ ๋งค๊ฐ๋ณ์๋ก ํ ์ง ๊ณ ๋ฏผํ๊ฒ ๋๋ค. ๊ฐ์ฒด๋ฅผ ๋งค๊ฐ๋ณ์๋ก ํ๋ฉด ํด๋น ๊ฐ์ฒด์ ์ธํฐํ์ด์ค์ ๊ฒฐํฉํด๋ฒ๋ฆฌ์ง๋ง ๊ฐ์ฒด์ ์ฌ๋ฌ ์์ฑ์ ์ ๊ทผํ ์ ์์ด ๋ด๋ถ ๋ก์ง์ด ๋ณต์กํด์ ธ๋ ํจ์๋ฅผ ์ผ์ผ์ด ์ฐพ์์ ๋ณ๊ฒฝํ ํ์๊ฐ ์๋ค. ์ค์ง์ ์ผ๋ก ํจ์์ ์บก์ํ ์์ค์ด ๋์์ง๋ ๊ฒ์ด๋ค. ์ค์ํ ๊ฒ์ ์ ๋ต์ด ์๋ค๋ ๊ฒ์ด๋ฉฐ, ์ด๋ป๊ฒ ์ฐ๊ฒฐํ๋ ๊ฒ์ด ๋ ๋์์ง ์ดํด๊ฐ ๋๋ค๋ฉด ๊ทธ๋ ์ฝ๋๋ฅผ ๊ฐ์ ํ๋ฉด ๋๋ค.
์๋๋ ๋ฆฌํฉํฐ๋ง ์ ์์ ํจ์ ์ ์ธ ๋ฐ๊พธ๊ธฐ ์ ์ฐจ๋ค.
๊ฐ๋จํ ์ ์ฐจ
๋งค๊ฐ๋ณ์๋ฅผ ์ ๊ฑฐํ๋ ค๊ฑฐ๋ ๋จผ์ ํจ์ ๋ณธ๋ฌธ์์ ์ ๊ฑฐ ๋์ ๋งค๊ฐ๋ณ์๋ฅผ ์ฐธ์กฐํ๋ ๊ณณ์ ์๋์ง ํ์ธํ๋ค.
๋ฉ์๋ ์ ์ธ์ ์ํ๋ ํํ๋ก ๋ฐ๊พผ๋ค.
๊ธฐ์กด ๋ฉ์๋ ์ ์ธ์ ์ฐธ์กฐํ๋ ๋ถ๋ถ์ ๋ชจ๋ ์ฐพ์์ ๋ฐ๋ ํํ๋ก ์์ ํ๋ค.
ํ ์คํธํ๋ค.
๋ง์ด๊ทธ๋ ์ด์ ์ ์ฐจ
์ด์ด์ง๋ ์ถ์ถ ๋จ๊ณ๋ฅผ ์์ํ๊ฒ ๋ง๋ค์ด์ผ ํ๋ค๋ฉด ํจ์์ ๋ณธ๋ฌธ์ ์ ์ ํ ๋ฆฌํฉํฐ๋งํ๋ค.
ํจ์ ๋ณธ๋ฌธ์ ์๋ก์ด ํจ์๋ก ์ถ์ถํ๋ค.
์ถ์ถํ ํจ์์ ๋งค๊ฐ๋ณ์๋ฅผ ์ถ๊ฐํด์ผ ํ๋ค๋ฉด '๊ฐ๋จํ ์ ์ฐจ'๋ฅผ ๋ฐ๋ผ ์ถ๊ฐํ๋ค.
ํ ์คํธํ๋ค
๊ธฐ์กด ํจ์๋ฅผ ์ธ๋ผ์ธํ๋ค.
์ด๋ฆ์ ์์๋ก ๋ถ์ฌ๋๋ค๋ฉด ํจ์ ์ ์ธ ๋ฐ๊พธ๊ธฐ๋ฅผ ํ ๋ฒ ๋ ์ ์ฉํด์ ์๋ ์ด๋ฆ์ผ๋ก ๋๋๋ฆฐ๋ค.
ํ ์คํธํ๋ค.
/* --------- ์๋ณธ --------- */function circum(radius) { return 2 * Math.PI * radius;}/* --------- ์ค๊ฐ --------- */function circum(radius) { return circumferencce(radius);}function circumference(radius) { return 2 * Math.PI * radius;}/* --------- ์๋ฃ --------- */function circumference(radius) { return 2 * Math.PI * radius;}/* --------- ์๋ณธ --------- */function addReservation(customer) { this._reservations.push(customer);}/* --------- ์ค๊ฐ 1 --------- */function addReservation(customer) { this.zz_addReservation(customer);}function zz_addReservation(customer) { this._reservations.push(customer);}/* --------- ์ค๊ฐ 2 --------- */function addReservation(customer) { this.zz_addReservation(customer, false);}function zz_addReservation(customer, isPriority) { this._reservations.push(customer);}/* --------- ์ค๊ฐ 3 --------- */function zz_addReservation(customer, isPriority) { assert(isPrioirty === true || isPriority === false); // ์ฌ์ฉํ๋ ํจ์๋ค ์ค์ ๋น ์ง ๋ถ๋ถ๋ค ํ์ธ(ํ์
์คํฌ๋ฆฝํธ๋ฉด ์์์) this._reservations.push(customer);}/* --------- ๋ง์ง๋ง --------- */function addReservation(customer, isPriority) { ...}๋ณ์ ์บก์ํ๋ ๋ณ์๋ฅผ ์ง์ ์ ๊ทผํ์ง ์๊ณ , ์ ๊ทผ ์ ์ด์๋ฅผ ํตํด ์ ๊ทผํ๊ฑฐ๋ ์์ ํ๋๋ก ๋ณ๊ฒฝํ๋ ๊ฒ์ ์๋ฏธํ๋ค.
์ ์์ ๋ฐ๋ฅด๋ฉด ํจ์๋ ๋ฐ์ดํฐ๋ณด๋ค ๋ค๋ฃจ๊ธฐ ์์ํ๋ค. ํจ์๋ฅผ ์ฌ์ฉํ๋ค๋ ๊ฑด ๋์ฒด๋ก ํธ์ถํ๋ค๋ ๋ป์ด๊ณ , ํจ์์ ์ด๋ฆ์ ๋ฐ๊พธ๊ฑฐ๋ ๋ค๋ฅธ ๋ชจ๋๋ก ์ฎ๊ธฐ๊ธฐ๋ ์ด๋ ต์ง ์๋ค. ์ฌ์ฐจํ๋ฉด ๊ธฐ์กด ํจ์๋ ๊ทธ๋๋ก ๋๊ณ ์ ๋ฌ ํจ์๋ก ํ์ฉํ ์๋ ์๋ค.
๋ฐ๋๋ก ๋ฐ์ดํฐ๋ ํจ์๋ณด๋ค ๋ค๋ฃจ๊ธฐ ๊น๋ค๋กญ๋ค. ์๋ํ๋ฉด ์์ ๊ฐ์ด ์ฒ๋ฆฌํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค. ๋ฐ์ดํฐ๋ ์ฐธ์กฐํ๋ ๋ชจ๋ ๋ถ๋ถ์ ํ๋ฒ์ ๋ฐ๊ฟ์ผ ์ฝ๋๊ฐ ์ ๋๋ก ๋์ํ๋ค. ๊ทธ๋ฆฌ๊ณ ์์ ๋ณ์ฏ์ฒ๋ผ ์ ํจ๋ฒ์๊ฐ ์์ฃผ ์ข์ ๋ฐ์ดํฐ๋ ์ด๋ ต์ง ์์ง๋ง, ๋์ ๋ฐ์ดํฐ๋ ๋ค๋ฃจ๊ธฐ ์ด๋ ค์์ง๋ค.
๊ทธ๋์ ์ ๊ทผํ ์ ์๋ ๋ฒ์๊ฐ ๋์ ๋ฐ์ดํฐ๋ฅผ ์ฎ๊ธธ ๋๋ ๋จผ์ ๊ทธ ๋ฐ์ดํฐ๋ก์ ์ ๊ทผ์ ๋ ์ ํ๋ ํจ์๋ฅผ ๋ง๋๋ ์์ผ๋ก ์บก์ํํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ผ ๋๊ฐ ๋ง๋ค. ๋ฐ์ดํฐ ์ฌ๊ตฌ์ฑ์ด๋ผ๋ ์ด๋ ค์ด ์์ ์ ํจ์ ์ฌ๊ตฌ์ฑ์ด๋ผ๋ ๋ ๋จ์ํ ์์ ์ผ๋ก ๋ณํํ๋ ๊ฒ์ด๋ค.
์ ์์ ๋ฐ๋ฅด๋ฉด ๋ฐ์ดํฐ ์บก์ํ๋ ๋ค๋ฅธ ๊ฒฝ์ฐ์๋ ๋์์ ์ค๋ค. ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ๊ณ ์ฌ์ฉํ๋ ์ฝ๋๋ฅผ ๊ฐ์ํ ์ ์๋ ํ์คํ ํต๋ก๊ฐ ๋์ด์ฃผ๊ธฐ ๋๋ฌธ์ ๋ฐ์ดํฐ ๋ณ๊ฒฝ ์ ๊ฒ์ฆ์ด๋ ๋ณ๊ฒฝ ํ ์ถ๊ฐ ๋ก์ง์ ์ฝ๊ฒ ๋ผ์ด๋ฃ์ ์ ์๋ค. ๊ทธ๋์ ์ ์๋ ์ ํจ๋ฒ์๊ฐ ํจ์ ํ๋๋ณด๋ค ๋์ ๊ฐ๋ณ ๋ฐ์ดํฐ๋ ๋ชจ๋ ์ด๋ฐ์์ผ๋ก ์บก์ํํด์ ๊ทธ ํจ์๋ฅผ ํตํด์๋ง ์ ๊ทผํ๊ฒ ๋ง๋๋ ์ต๊ด์ด ์๋ค๊ณ ํ๋ค. (๋ฐ์ดํฐ์ ๋ํ ๊ฒฐํฉ๋๋ ๋์์ง์ง ์์ ์ ์๋ค.)
๊ฐ์ฒด ์งํฅ์์ ๊ฐ์ฒด์ ๋ฐ์ดํฐ๋ฅผ ํญ์ private์ผ๋ก ์ ์งํ๋ผ๊ณ ๊ฐ์กฐํ๋ ์ด์ ๊ฐ ๋ฐ๋ก ์ฌ๊ธฐ์ ์๋ค๊ณ ํ๋ค. ๊ทธ๋ฆฌ๊ณ ์๊ฐ ์บก์ํ๋ฅผ ์ฃผ์ฅํ๋ ์ฌ๋๋ ์๋ค๊ณ ํ๋ค(ํด๋์ค ๋ด์์๋ ํ๋ ์ฐธ์กฐํ ๋ ์ ๊ทผ์๋ฅผ ํตํด์ ์ ๊ทผํด์ผ ํ๋ค๊ณ ์ฃผ์ฅํ๋ ์ฌ๋). ๊ทธ๋ฐ๋ฐ ์ ์๋ ์ด๊ฑด ์ง๋์น์ง ์๋๋ผ๋ ์๊ฒฌ์ ๋๊ณ , ๊ทธ ์ ๋๋ก ์บก์ํํด์ผํ ์ ๋๋ก ํด๋์ค๊ฐ ํฌ๋ค๋ฉด ์๊ฒ ์ชผ๊ฐ์ผํ๋ค๊ณ ์ฃผ์ฅํ๋ค.
๊ทธ๋ฆฌ๊ณ ๋ถ๋ณ ๋ฐ์ดํฐ๋ ๊ฐ๋ณ๋ฐ์ดํฐ๋ณด๋ค ์บก์ํํ ์ด์ ๊ฐ ์ ๋ค. ๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝ๋ ์ผ์ด ์์ด์ ๊ฐฑ์ ์ ๊ฒ์ฆ ๊ฐ์ ์ถ๊ฐ ๋ก์ง์ด ์๋ฆฌํ ๊ณต๊ฐ์ ๋ง๋ จํ ํ์๊ฐ ์๊ธฐ ๋๋ฌธ์ด๋ค. ๊ทธ๋ฆฌ๊ณ ๋ถ๋ณ ๋ฐ์ดํฐ๋ ์ฎ๊ธธ ํ์ ์์ด ๋ณต์ ํ๋ฉด ๋๋ค.
์๋๋ ๋ฆฌํฉํฐ๋ง ์ ์๊ฐ ์ค๋ช ํ๋ ์ ์ฐจ๋ค.
์ ์ฐจ
๋ณ์๋ก์ ์ ๊ทผ๊ณผ ๊ฐฑ์ ์ ์ ๋ดํ๋ ์บก์ํ ํจ์๋ค์ ๋ง๋ ๋ค.
์ ์ ๊ฒ์ฌ๋ฅผ ์ํํ๋ค.
๋ณ์๋ฅผ ์ง์ ์ฐธ์กฐํ๋ ๋ถ๋ถ์ ๋ชจ๋ ์ ์ ํ ์บก์ํ ํจ์ ํธ์ถ๋ก ๋ฐ๊พผ๋ค. ํ๋์ฉ ๋ฐ๊ฟ ๋๋ง๋ค ํ ์คํธํ๋ค.
๋ณ์์ ์ ๊ทผ ๋ฒ์๋ฅผ ์ ํํ๋ค.
ํ ์คํธํ๋ค.
๋ณ์ ๊ฐ์ด ๋ ์ฝ๋๋ผ๋ฉด ๋ ์ฝ๋ ์บก์ํํ๊ธฐ๋ฅผ ์ ์ฉํ ์ง ๊ณ ๋ คํด๋ณธ๋ค.
// defaultOwner.jslet defaultOwner = {firstName:"๋งํด", lastName:"ํ์ธ๋ฌ"};export function defaultOwner() {return defaultOwnerData};export function setDefaultOwner(arg) {defaultOwnerData = arg};// ๊ทผ๋ฐ ์ ๋ฐฉ์์ ๋ง์ฝ ์ฌ๋ฌ ํ์ผ์์ ๊ฐ์ ธ๋ค ์ฌ์ฉํ๊ณ , ์์ ํ๋ค๋ฉด ํ๋์ ํ์ผ ์์ ํ ๋ ๋ค๋ฅธ ํ์ผ์๋ ์ํฅ์ ์ค ์ ์๋ค.//defaultOwner.js ๊ทธ๋์ ์๋์ ๊ฐ์ด Object.assign์ผ๋ก ์์ ๋ณต์ฌ๋ฅผ ํด์ ์ฃผ๊ธฐ๋ ํ๋ค. Setter์๋ ๋ณต์ฌํด์ ์ฃผ๊ธฐ๋ ํ๋ค.let defaultOwner = {firstName:"๋งํด", lastName:"ํ์ธ๋ฌ"};export function defaultOwner() {return Object.assign({},defaultOwnerData)};export function setDefaultOwner(arg) {defaultOwnerData = arg};// ํ์ง๋ง ์ ๋ฐฉ๋ฒ๋ค์ ๊ฐ๋ณ ํ๋์ ๋ํ ์ ๊ทผ์ ์กฐ์ ํ๊ธฐ ํ๋ค๋ค. ๊ทธ๋์ Class๋ก ๋ ์ฝ๋ ์บก์ํ๋ฅผ ํ๊ธฐ๋ํ๋ค.๋ณ์ ์ด๋ฆ ๋ฐ๊พธ๊ธฐ๋ ๊ฐ๋จํ ์์๋ง ์ง๊ณ ๋์ด๊ฐ๊ฒ ๋ค.
/* ์ */let a = height * width;const cpyNm = "๊ตฌ๊ธ";/* ํ */let area = height * width;const companyName = "๊ตฌ๊ธ";DDD ํ๊ฒฝ์์๋ ์ถ์ฝ์ด๊ฐ ์ฝ์๋ ์ธ์ด๋ผ๋ฉด ๊ทธ๋๋ก ์ฐ๋ ๊ฒ์ด ๋ง์ ๊ฒ์ด๋ค. ์ํฉ์ ๋ง๊ฒ ์ฐ์.
์ ์๋ ๋ฐ์ดํฐ ํญ๋ชฉ ์ฌ๋ฌ ๊ฐ๊ฐ ์ด ํจ์์์ ์ ํจ์๋ก ํจ๊ป ๋ชฐ๋ ค๋ค๋๋ ๊ฒฝ์ฐ๋ฅผ ์์ฃผ ๋ณธ๋ค๊ณ ํ๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๋ฐ ๋ฐ์ดํฐ ๋ฌด๋ฆฌ๋ฅผ ๋ฐ๊ฒฌํ๋ฉด ํ๋์ ๊ตฌ์กฐ๋ก ๋ฌถ์ด์ค๋ค๊ณ ํ๋ค.
๋ฐ์ดํฐ ๋ญ์น๋ฅผ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ก ๋ฌถ์ผ๋ฉด ๋ฐ์ดํฐ ์ฌ์ด์ ๊ด๊ณ๊ฐ ๋ช ํํด์ง๋ฉฐ, ํจ์๋ ๋งค๊ฐ๋ณ์ ์๊ฐ ์ค์ด๋ ๋ค. ๊ทธ๋ฆฌ๊ณ ๊ฐ์ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ๋ ๋ชจ๋ ํจ์๊ฐ ์์๋ฅผ ์ฐธ์กฐํ ๋ ํญ์ ๋๊ฐ์ ์ด๋ฆ์ ์ฌ์ฉํด์ ์ผ๊ด์ฑ๋ ๋์์ง๋ค.
ํ์ง๋ง ์ด ๋ฆฌํฉํฐ๋ง์ ์ง์ ํ ํ์ ์ฝ๋๋ฅผ ๋ ๊ทผ๋ณธ์ ์ผ๋ก ๋ฐ๊ฟ์ค๋ค๋ ๊ฒ์ด๋ค. ๋ฐ์ดํฐ ๊ตฌ์กฐ์ ๋ด๊ธธ ๋ฐ์ดํฐ์ ๊ณตํต์ผ๋ก ์ ์ฉ๋๋ ๋์์ ์ถ์ถํด์ ํจ์๋ก ๋ง๋ค ์ ์๋ค. ์ด ๊ณผ์ ์์ ์๋ก ๋ง๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ๊ฐ ๋ฌธ์ ์์ญ์ ํจ์ฌ ๊ฐ๊ฒฐํ๊ฒ ํํํ๋ ์๋ก์ด ์ถ์ ๊ฐ๋ ์ผ๋ก ๊ฒฉ์๋๋ฉด์, ์ฝ๋์ ๊ฐ๋ ์ ์ธ ๊ทธ๋ฆผ์ ๋ค์ ๊ทธ๋ฆด ์๋ ์๋ค.
์๋๋ ์ ์๊ฐ ์๊ฐํ ์ ์ฐจ์ด๋ค.
์ ์ฐจ
์ ๋นํ ๋ฐ์ดํฐ ๊ตฌ์กฐ๊ฐ ์์ง ๋ง๋ จ๋์ด ์์ง ์๋ค๋ฉด ์๋ก ๋ง๋ ๋ค.
ํ ์คํธํ๋ค.
ํจ์ ์ ์ธ ๋ฐ๊พธ๊ธฐ๋ก ์ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ๋งค๊ฐ๋ณ์๋ก ์ถ๊ฐํ๋ค.
ํ ์คํธํ๋ค.
ํจ์ ํธ์ถ ์ ์๋ก์ด ๋ฐ์ดํฐ ๊ตฌ์กฐ ์ธ์คํด์ค๋ฅผ ๋๊ธฐ๋๋ก ์์ ํ๋ค. ํ๋์ฉ ์์ ํ ๋๋ง๋ค ํ ์คํธํ๋ค.
๊ธฐ์กด ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ๋ ์ฝ๋๋ฅผ ์ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ ์์๋ก ์ฌ์ฉํ๋๋ก ๋ฐ๊พผ๋ค.
๋ค ๋ฐ๊ฟจ๋ค๋ฉด ๊ธฐ์กด ๋งค๊ฐ๋ณ์๋ฅผ ์ ๊ฑฐํ๊ณ ํ ์คํธํ๋ค.
const station = { name:"123", readings: [ {temp:47, time:100}, {temp:35, time:101}, {temp:30, time:102}, ]}/* ์ฒ์ */function readingOutsideRange(station, min, max) { return station.readings.filter(r => r.temp < min || r.temp > max);}const alerts = readingOutsideRange(station, operatingPlan.temperatureFloor, operatingPlan.temperatureCeiling);/* ๊ฐ์ ํ + ๋งค๊ฐ๋ณ์ ๊ฐ์ฒด ํ์ฉ ๋ฉ์๋ ์ถ๊ฐ */class NumberRange { constructor(min, max) { this._data = {min,max}; } contains(value) { return this._data.min <= value && value <= this._data.max ; }}function readingOutsideRange(station, range) { return station.readings.filter(r => !range.contains(r.temp));}const range = new NumberRange(operatingPlan.temperatureFloor, operatingPlan.temperatureCeiling);const alerts = readingOutsideRange(station, range);์ ์์ ๋ฐ๋ฅด๋ฉด ํด๋์ค๋ ๋ฐ์ดํฐ์ ํจ์๋ฅผ ํ๋์ ๊ณต์ ํ๊ฒฝ์ผ๋ก ๋ฌถ์ ํ, ๋ค๋ฅธ ํ๋ก๊ทธ๋จ ์์์ ์ด์ฐ๋ฌ์ง ์ ์๋๋ก ๊ทธ์ค ์ผ๋ถ๋ฅผ ์ธ๋ถ์ ์ ๊ณตํ๋ ๊ฒ์ด๋ค. ์ ์๋ ํจ์ ํธ์ถ ์ ์ธ์๋ก ์ ๋ฌ๋๋ ๊ณตํต ๋ฐ์ดํฐ๋ฅผ ์ค์ฌ์ผ๋ก ๊ธด๋ฐํ๊ฒ ์ฎ์ด ์๋ํ๋ ํจ์ ๋ฌด๋ฆฌ๋ฅผ ๋ฐ๊ฒฌํ๋ฉด ํด๋์ค ํ๋๋ก ๋ฌถ๊ณ ์ ์๋ํ๋ค๊ณ ํ๋ค. ํด๋์ค๋ก ๋ฌถ์ผ๋ฉด ๊ณต์ ํ๋ ๊ณตํต ํ๊ฒฝ์ ๋ ๋ช ํํ ํํํ ์ ์๊ณ , ๊ฐ ํจ์์ ์ ๋ฌ๋๋ ์ธ์๋ฅผ ์ค์ฌ์ ๊ฐ์ฒด ์์์์ ํจ์ ํธ์ถ์ ๊ฐ๊ฒฐํ๊ฒ ๋ง๋ค ์ ์๊ธฐ ๋๋ฌธ์ด๋ค. ๋ํ ์ด ๊ฐ์ฒด๋ ๋ค๋ฅธ ์์คํ ์ ์ ๋ฌํ๋ ์ฐธ์กฐ๊ฐ ๋ ์ ๋ ์๋ค.
๋ฌผ๋ก ํด๋์ค ๋ง๊ณ ๋ ํจ์๋ก ๋ฌถ๊ธฐ๋ ๊ฐ๋ฅํ๋ค. ํด๋์ค๋ก ๋ฌถ์ ๋๋ ํด๋ผ์ด์ธํธ๊ฐ ๊ฐ์ฒด์ ํต์ฌ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ ์ ์๊ณ , ํ์ ๊ฐ์ฒด๋ค์ ์ผ๊ด๋๊ฒ ๊ด๋ฆฌํ ์ ์๋ค. ๋ฌผ๋ก ์ค์ฒฉ ํจ์ ํํ๋ก ๋ฌถ์ด๋ ๋์ง๋ง, ํ ์คํธํ ๋ ๊น๋ค๋ก์ธ ์ ์๋ค๊ณ ํ๋ค. ์๋ํ๋ฉด ์ธ๋ถ์ ๊ณต๊ฐํ ํจ์๊ฐ ์ฌ๋ฌ ๊ฐ์ผ ๋๋ ํด๋์ค๋ฅผ ์ฌ์ฉํ ์ ๋ฐ์ ์๋ค๊ณ ์ ์๊ฐ ์ธ๊ธํ๋ค. (์์ฆ์ hooks ํํ๋ก ๋ค ์ ๋ฌถ๋ ๊ฒ ๊ฐ๋ค.);
์๋๋ ์ ์์ ์ ์ฐจ์ด๋ค.
์ ์ฐจ
ํจ์๋ค์ด ๊ณต์ ํ๋ ๊ณตํต ๋ฐ์ดํฐ ๋ ์ฝ๋๋ฅผ ์บก์ํํ๋ค.
๊ณตํต ๋ ์ฝ๋๋ฅผ ์ฌ์ฉํ๋ ํจ์ ๊ฐ๊ฐ์ ์ ํด๋์ค๋ก ์ฎ๊ธด๋ค.(์บก์ํํ ๋ ์ฝ๋๋ก)
๋ฐ์ดํฐ๋ฅผ ์กฐ์ํ๋ ๋ก์ง๋ค์ ํจ์๋ก ์ถ์ถํด์ ์ ํด๋์ค๋ก ์ฎ๊ธด๋ค.
/* ์ ์ฉ ์ */const reading = {customer:"ivan", quantity: 10, month:5, year:2025};const baseCharge = baseRate(reading.month, reading.year) * reading.quantity;const texableCahrge = Math.max(0, baseCharge-taxThreshold(reading.year));/* ์ ์ฉ ํ */class Reading { constructor(data) { this._customer = data.customer; this._quantity = data.quantity; ... } get customer() {return this._customer} ... get baseCharge() { return baseRate(this.month, this.yaer) * this.quantity); } get taxableChargeFn() { return Math.max(0, this.baseCharge - taxThreshold(this.year); }}const aReading = new Reading(reading);const taxableCharge = aReading.texableCharge;์ด ๋ฆฌํฉํฐ๋ง ๋ฐฉ๋ฒ์ ํด๋์ค ๋ฌถ๊ธฐ์ ์ ์ฌํ๋ค. ๋ค๋ง ์ด๋ ํ ์ ๋ณด๊ฐ ์ฌ์ฉ๋๋ ๊ณณ๋ง๋ค ๊ฐ์ ๋์ถ ๋ก์ง์ด ๋ฐ๋ณต๋๋๋ฐ, ์ด๋ฌํ ๋์ถ ์์ ๋ค์ ํ๋๋ก ๋ชจ์ผ๋๋ฐ ์ฌ์ฉ๋๋ค. ์๋ฅผ ๋ค๋ฉด ๊ฒ์๊ณผ ๊ฐฑ์ ์ ์ผ๊ด๋ ์ฅ์์์ ์ฒ๋ฆฌํ๋ฉฐ ๋ก์ง ์ค๋ณต์ ๋ง์ ์ ์๋ค.
์๋ณธ ๋ฐ์ดํฐ๋ฅผ ์ ๋ ฅ๋ฐ์์ ํ์ํ ์ ๋ณด๋ฅผ ๋ชจ๋ ๋์ถํ ๋ค ๊ฐ๊ฐ์ ์ถ๋ ฅ ๋ฐ์ดํฐ์ ํ๋์ ๋ฃ์ด ๋ฐํํ๋ ๋ฐฉ์์ด๋ค. ์ ์๋ ์๋ณธ ๋ฐ์ดํฐ๊ฐ ์ฝ๋ ์์์ ๊ฐฑ์ ๋ ๋๋ ํด๋์ค๋ก ๋ฌถ๋ ๊ฒ์ ์ ํธํ๋ค๊ณ ํ๋ค. (์์ฆ์ ๋ฆฌ์กํธ๋ฅผ ์จ์ ์ปค์คํ ํ ์ผ๋ก ์ ์ฐ๋ ๊ฒ ๊ฐ๋ค.)
ํด๋์ค๋ก ๋ฌถ๋ ๊ฒ๊ณผ ๋น์ทํด์ ์์๋ง ์ค๋ช ํ๊ณ ๋์ด๊ฐ๊ฒ ๋ค.
/* ์ ์ฉ ์ */const reading = {customer:"ivan", quantity: 10, month:5, year:2025};const baseCharge = baseRate(reading.month, reading.year) * reading.quantity;const texableCharge = Math.max(0, baseCharge-taxThreshold(reading.year));/* ์ ์ฉ ํ */function enrichReading(original) { const result = _.cloneDeep(original); result.baseCharge = baseRate(reading.month, reading.year) * reading.quantity; result.texableCharge = Math.max(0, baseCharge-taxThreshold(reading.year)); return result;}const aReading = enrichReading(reading);const texableCharge = aReading.texableCharge;์ ์๋ ์๋ก ๋ค๋ฅธ ๋ ๋์์ ํ๊บผ๋ฒ์ ๋ค๋ฃจ๋ ์ฝ๋๋ฅผ ๋ฐ๊ฒฌํ๋ฉด ๊ฐ๊ฐ์ ๊ฐ๋ณ ๋ชจ๋๋ก ๋๋๋ ๋ฐฉ๋ฒ์ ๋ชจ์ํ๋ค๊ณ ํ๋ค. ์ฝ๋๋ฅผ ์์ ํ ๋ ๋ ๋์์ ๋์์ ์๊ฐํ ํ์ ์์ด ํ๋์๋ง ์ง์คํ๊ธฐ ์ํด์๋ค. ์ด๋ ๊ฒ ๋ถ๋ฆฌํ๋ ๊ฐ์ฅ ์ฌ์ด ๋ฐฉ๋ฒ์ ๋ ๋จ๊ณ๋ก ๋๋๋ ๊ฒ์ด๋ค. ์๋ฅผ ๋ค๋ฉด ์ด๋ค ์ ๋ ฅ์ด ์ฒ๋ฆฌ ๋ก์ง์ ์ ํฉํ์ง ์๋ค๋ฉด ์ด๋ฅผ ๋จ๊ณ๋ฅผ ๋๋ ๋ค๋ฃจ๊ธฐ ํธํ ํํ๋ก ๊ฐ๊ณตํ๋ ๋จ๊ณ๋ก ๋ถ๋ฆฌํ๋ ๊ฒ์ด๋ค.
์๋๋ ์ ์์ ๋จ๊ณ ์ชผ๊ฐ๊ธฐ ์ ์ฐจ์ด๋ค.
์ ์ฐจ
๋ ๋ฒ์งธ ๋จ๊ณ์ ํด๋นํ๋ ์ฝ๋๋ฅผ ๋ ๋ฆฝ ํจ์๋ก ์ถ์ถํ๋ค.
ํ ์คํธํ๋ค.
์ค๊ฐ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค์ด์ ์์์ ์ถ์ถํ ํจ์์ ์ธ์๋ก ์ถ๊ฐํ๋ค.
ํ ์คํธํ๋ค.
์ถ์ถํ ๋ ๋ฒ์งธ ๋จ๊ณ ํจ์์ ๋งค๊ฐ๋ณ์๋ฅผ ํ๋์ฉ ๊ฒํ ํ๋ค. ๊ทธ์ค ์ฒซ ๋ฒ์งธ ๋จ๊ณ์์ ์ฌ์ฉ๋๋ ๊ฒ์ ์ค๊ฐ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ก ์ฎ๊ธด๋ค. ํ๋์ฉ ์ฎ๊ธธ ๋๋ง๋ค ํ ์คํธํ๋ค.
์ฒซ ๋ฒ์งธ ๋จ๊ณ ์ฝ๋๋ฅผ ํจ์๋ก ์ถ์ถํ๋ฉด์ ์ค๊ฐ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ๋ฐํํ๋๋ก ๋ง๋ ๋ค.
/* ์ชผ๊ฐ๊ธฐ ์ */function priceOrder(product, quantity, shippingMethod) { const basePrice = product.basePrice * quantity; const discount = Math.max(quantity - product.discountThreshold, 0) * product.basePrice * product.discountRate; const shippingPerCase = (basePrice > shippingMethod.discountThreshold) ? shippingMethod.discountedFee : shippingMethod.feePerCase; const shippingCost = quantity * shippingPerCase; const price = basePrice - discount + shippingCost; return price;}/* ์ชผ๊ฐ๊ธฐ ์ค๊ฐ 1 (๋
๋ฆฝ ํจ์ ์ถ์ถ) */function priceOrder(product, quantity, shippingMethod) { const basePrice = product.basePrice * quantity; const discount = Math.max(quantity - product.discountThreshold, 0) * product.basePrice * product.discountRate; const price = applyShipping(basePrice, shippingMethod, quantity, discount); return price;}function applyShipping(basePrice, shippingMethod, quantity, discount) { const shippingPerCase = (basePrice > shippingMethod.discountThreshold) ? shippingMethod.discountedFee : shippingMethod.feePerCase; const shippingCost = quantity * shippingPerCase; const price = basePrice - discount + shippingCost; return price;}/* ์ชผ๊ฐ๊ธฐ ์ค๊ฐ 2 (์ค๊ฐ ๋ฐ์ดํฐ ๊ตฌ์กฐ ์ถ๊ฐ) */function priceOrder(product, quantity, shippingMethod) { const basePrice = product.basePrice * quantity; const discount = Math.max(quantity - product.discountThreshold, 0) * product.basePrice * product.discountRate; const priceData = {basePrice, quantity, discount}; const price = applyShipping(priceData, shippingMethod); return price;}function applyShipping(priceData, shippingMethod) { const shippingPerCase = (priceData.basePrice > shippingMethod.discountThreshold) ? shippingMethod.discountedFee : shippingMethod.feePerCase; const shippingCost = priceData.quantity * shippingPerCase; const price = priceData.basePrice - priceData.discount + shippingCost; return price;}/* ์ชผ๊ฐ๊ธฐ ์ค๊ฐ 3 (์ค๊ฐ ๋ฐ์ดํฐ ๊ตฌ์กฐ ๋ฐํ ์ถ๊ฐ) */function priceOrder(product, quantity, shippingMethod) { const priceData = calculatePricingData(product, quantity); const price = applyShipping(priceData, shippingMethod); return price;}function calculatePricingData(product, quantity) { const basePrice = product.basePrice * quantity; const discount = Math.max(quantity - product.discountThreshold, 0) * product.basePrice * product.discountRate; return {basePrice, quantity, discount};}function applyShipping(priceData, shippingMethod) { const shippingPerCase = (priceData.basePrice > shippingMethod.discountThreshold) ? shippingMethod.discountedFee : shippingMethod.feePerCase; const shippingCost = priceData.quantity * shippingPerCase; const price = priceData.basePrice - priceData.discount + shippingCost; return price;}/* ์ชผ๊ฐ๊ธฐ ์ ์ฉ ํ ๊ธฐํ ํจ์ ์๋ต. */function priceOrder(product, quantity, shippingMethod) { const priceData = calculatePricingData(product, quantity); return applyShipping(priceData, shippingMethod);}์๋ฐ์คํฌ๋ฆฝํธ๋ก ์ค๋ช ํ์ง๋ง ์ฌ์ค ์๋ฐ๋ฅผ ์ฌ์ฉํ๋ ์ฌ๋๋ค์๊ฒ ๋ ๋์์ด ๋์ ๊ฒ ๊ฐ์ต๋๋ค. ์๋ํ๋ฉด ํ์ฌ ํ๋ก ํธ์๋์ ์๋ฐ์คํฌ๋ฆฝํธ์์๋ Class๋ฅผ ์ฌ์ฉํ์ฌ ์ธ์คํด์ค๋ก ์ํ๊ด๋ฆฌ๋ฅผ ํ๊ธฐ์๋ isObject๋ก ๊ฐ์ ๊ฐ์ฒด์ธ์ง ๊ฒ์ฌํ์ฌ ์ํ ๋ณํ๋ฅผ ์ฒดํฌํ๋ React๊ฐ์ ํ๋ ์์ํฌ์์๋ ์ข ํ๋ค๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋ณ์ 1๊ฐ๋ฅผ ๋ฐ๊พธ๋ฉด ์ธ์คํด์ค๋ฅผ ๋ค์ ์์ฑํด์ ๊ฐ๋ค์ ๋ฃ์ด์ค์ผ ํ๋ฉด๊น์ง ๋ฐ์์ด ๋๊ธฐ ๋๋ฌธ์ ๋๋ค..(์ง์ ํด๋ณด๊ณ ๊ณ ์ํด๋ด์ ์๊ณ ์์ต๋๋ค!! ์๋๋ฉด MobX๋ฅผ ์ฐ๋๊ฐ...)
๊ทธ๋๋ ์ค์ํ๊ฑด ์ด๋ป๊ฒ ๋ถ๋ฆฌ๋ฅผ ํ ๊น.. ์ด๋ป๊ฒ ๋ฆฌํฉํ ๋ง์ ํ ๊น ์ ๋๋ค. ๋ง์ด ๋ฆฌํฉํฐ๋ง์ด์ง ์ฌ์ค ํด๋ฆฐ์ฝ๋๋, ๋์์ธ ํจํด ์ฑ ์ ๋ณด๋๋ผ๋ ํฐ ์ค๊ธฐ๋ ๊ฐ์ ๊ฒ ๊ฐ์ต๋๋ค... ๊ทธ๋ฅ ๋ฆฌํฉํฐ๋ง์ ํ ๋ ๋จ๊ณ๋ณ๋ก ์ด๋ป๊ฒ ์ ์ฉํ ์ง๋ฅผ ์ ์๋ ค์ฃผ๋ ์ฑ ์ด ๋ฆฌํฉํฐ๋ง ์ฑ ์ธ๊ฒ ๊ฐ์ต๋๋ค. ๊ทธ๋๋ก ํ ์์ ์ ์์ต๋๋ค๋ง.. ์ฌ๋ฌ๋ถ๋ค ํจ๊ป ๋ณด๋ฉด์ ๋ง์ ๊ณต๋ถ ๋์ จ๊ธธ ๋น๋๋ค!!