๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿฟ Project

[SidePJ] ๊นƒํ—ˆ๋ธŒ Issue Cracker 1๋ถ€ - ํ”„๋กœ์ ํŠธ ์‹œ์ž‘

by Tamii 2021. 6. 29.
๋ฐ˜์‘ํ˜•

๋งˆ์ง€๋ง‰ ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ–ˆ๋‹ค! 

๋ฒŒ์จ๋ถ€ํ„ฐ ๋์ด ๋„ˆ๋ฌด ์•„์‰ฝ์ง€๋งŒ ๊ทธ๋ž˜๋„ ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ๋„ ๋”๋”๋” ์—ด์‹ฌํžˆ ํ•ด๋ณด๊ณ ์ž ํ•œ๋‹ค.

 

Issue Tracker Issue Cracker ๐Ÿช ์‹œ์ž‘! 

 

์ด๋ฒˆ ํ”„๋กœ์ ํŠธ๋Š” Raccon , pyro, ๋…ธ์„, Neo์™€ ํ•จ๊ป˜ํ•˜๋Š” 5์ธ ๋Œ€๊ฐ€์กฑ!!!!!! ( ๋‹ค๊ฐ™์ด ๋ฐฅ๋„ ๋ชป๋จน์Œ!@ )

์šฐ๋ฆฌ์˜ ๋ชฉํ‘œ๋Š” ์ด๊ฒƒ!

1) ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์™€ ์นœํ•ด์ง€๊ธฐ 

2) Recoil ์ด๋ž‘๋„ ์นœํ•ด์ง€๊ธฐ 

3) ์—๋Ÿฌ์ฒ˜๋ฆฌ์™€ ์ตœ์ ํ™”๊นŒ์ง€

4) CSS ๊ฐ•๋ฐ•์—์„œ ๋ฒ—์–ด๋‚˜์ž!!!! ( ๊ณผ์—ฐ ๋ ๊นŒ )

 

๋‹จ์ˆœํžˆ ๊นƒํ—ˆ๋ธŒ ์ด์Šˆ ํฌ๋ž˜์ปค ์™„์„ฑ์„ ๋„˜์–ด์„œ ๋ฆฌ์ฝ”์ผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ฐํ•˜๊ฒŒ ์ดํ•ดํ•˜๊ณ  ์ง์ ‘ ๊ตฌํ˜„ํ•ด๋ณด๋Š” ์‹œ๊ฐ„์„ ๊ฐ€์งˆ ์˜ˆ์ •์ด๋‹ค.

๊ทธ๋Ÿฌ๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ฒซ์ฃผ๋ถ€ํ„ฐ ๋‹ฌ๋ ค์•ผ ํ•˜๋Š”๋ฐ ๋ฉด์ ‘์ด ํ•˜๋‚˜ ์žˆ์–ด์„œ ๋งˆ์Œ์ด ๊ธ‰ํ•˜๊ธด ํ•˜์ง€๋งŒ ์—ด์‹ฌํžˆ ํ•ด๋ด์•ผ์ง€! 

๊ฒŒ์‹œ๊ธ€์„ ์“ฐ๋˜ ์ค‘์— ํƒ€์ž…์—๋Ÿฌ์ธ ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์•„  ํƒ€์ž…์—๋Ÿฌ์ธ ๊ฒฝ์šฐ์— #type ํƒœ๊ทธ๋ฅผ ๋ถ™์—ฌ๋†“๊ฒ ์Šต๋‹ˆ๋‹ค ๐Ÿ˜œ

 


๐Ÿ“Œ Typescirpt ๋กœ OAuth ๊ตฌํ˜„!

typescirpt ๋กœ OAuth ๊ตฌํ˜„ํ•ด๋ณด๋ฉฐ ๊ฒช์€ ๋‚œ๊ด€๋“ค

 

1) Callback.tsx ์˜ ํƒ€์ž… #type

 

import { RouteComponentProps } from 'react-router-dom';

const Callback = ({ history, location }: RouteComponentProps): JSX.Element => {
  const authUri = `http://`
  const { code } = qs.parse(location.search, {
        ignoreQueryPrefix: true,
      });
    
    //์ค‘๋žต
   history.push('/main/issue-list');
   //์ค‘๋žต

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ฒ˜์Œ์ด๋‹ค ๋ณด๋‹ˆ  React ์˜ Component๋กœ return ํ•œ ๊ฒƒ์ด ์ •ํ™•ํžˆ ์–ด๋–ค ํƒ€์ž…์ธ์ง€ ํ—ค๋งธ๋Š”๋ฐ, 

JSX.Element์˜€๋‹ค .

๊ทธ๋ฆฌ๊ณ  Callback ์•ˆ์—์„œ ์‚ฌ์šฉํ•˜๋Š” history์™€ location ์˜ ํƒ€์ž…์€ RouteComponentProps๋‹ค

 

์‹ค์ œ RoutComponentProps  ๋‚ด๋ถ€๋ฅผ ๋œฏ์–ด๋ณด๋ฉด  ์ด๋ ‡๊ฒŒ ์ƒ๊ฒผ๋‹ค.

export interface RouteComponentProps<
    Params extends { [K in keyof Params]?: string } = {},
    C extends StaticContext = StaticContext,
    S = H.LocationState
> {
    history: H.History<S>;
    location: H.Location<S>;
    match: match<Params>;
    staticContext?: C;
}

 

โœ… small Tip~

์ฒ˜์Œ ์ฝ”๋“œ ๊ตฌํ˜„ ์‹œ์—๋Š” ํƒ€์ž…์–ด๋–ค๊ฑธ ์ง€์ •ํ•˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์–ด์„œ ์—„์ฒญ ํ•ด๋งธ๋Š๋ฐ , 

mac๊ธฐ์ค€ ( command + ํด๋ฆญ) ํ•˜๋ฉด ํ•ด๋‹น ํƒ€์ž…์˜ ๋‚ด๋ถ€๋ฅผ ๋œฏ์–ด๋ณผ ์ˆ˜ ์žˆ๋‹ค! ๋งค์šฐ ์ข‹์Œ (๋ผ์ฟค์ด ์€์—ฐ์ค‘์— ์•Œ๋ ค์ฃผ์‹ฌ) 

 

 

 

 

 


๐Ÿ“Œ Typescirpt๋กœ Material UI ์‚ฌ์šฉ๊ธฐ

โ–  Icon Tabs ์ปค์Šคํ…€ ์Šคํƒ€์ผ ์ž…ํžˆ๊ธฐ

๊ธฐ๋ณธ
Expected

์›๋ž˜ ์ด๋ ‡๊ฒŒ ์•„์ด์ฝ˜๊ณผ ๋ผ๋ฒจ์ด coloumnํ˜•ํƒœ๋กœ ๋˜์–ด ์žˆ๋Š๋ฐ, ๋‚ด๊ฐ€ ํ•˜๊ณ ์‹ถ์€๊ฑด  ์•„๋ž˜์™€ ๊ฐ™์€  row ์ •๋ ฌ ๊ณผ ํฌ๊ธฐ ์กฐ์ •

 

1) row ์ •๋ ฌ

์›๋ณธ

 <Tab icon={<FlagIcon />} label="๋งˆ์ผ์Šคํ†ค" />

์ˆ˜์ •

<Tab
        className={classes.tabWrapper}
        label={
          <div>
            <FlagIcon style={{ verticalAlign: 'middle' }} /> ๋งˆ์ผ์Šคํ†ค
          </div>
        }
      />

์ด๋ ‡๊ฒŒ ๋ฐ”๊ฟ”์คŒ์œผ๋กœ์จ ๊ฒจ์šฐ ์„ฑ๊ณต!!!!!!!

์ฐธ๊ณ : https://github.com/mui-org/material-ui/issues/11653

 

 

 

2)  click Handler #type

์ฒ˜์Œ meterial UI์˜ Tab์„ ์‚ฌ์šฉํ•˜๋Š” ์ค‘์— ์ด๋ฒคํŠธ ํƒ€์ž… ์ง€์ •์—์„œ  ๊ณ„์† ์˜ค๋ฅ˜๊ฐ€ ๋‚ฌ๋‹ค.

 

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ๋‹จํ•˜๋‚˜์˜ ์žฅ์  (??)์ธ ์ œ์•ˆ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๋‹ˆ Record<string, never >๋ฅผ ๋„ฃ์–ด๋ณด๋ผํ•ด์„œ ๋„ฃ์—ˆ๋”๋‹ˆ ์–ด๋–จ๊ฒฐ์— ์„ฑ๊ณต.?

export default function TabList(): JSX.Element {
  const classes = useStyles();
  const [value, setValue] = React.useState(0);

  const handleChange = (
    event: React.ChangeEvent<Record<string, unknown>>,
    newValue: number
  ) => {
    setValue(newValue);
  };

  return (
    <Tabs
      value={value}
      onChange={handleChange}

* never ๊ณผ unknown ์˜ ์ฐจ์ด๋Š”  -> https://simsimjae.tistory.com/464

์ฐธ๊ณ :https://github.com/mui-org/material-ui/issues/17454 

 

3) style custom

Material UI๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ ๊ฐ€์žฅ ๋ถˆํŽธํ•œ ์ ์€ style-components๋กœ customํ•˜๊ฒŒ ์Šคํƒ€์ผ์ง€์ •ํ•˜๊ธฐ๊ฐ€ ์–ด๋ ต๋‹ค๋Š” ์  , ๊ทธ๋กœ ์ธํ•ด ๋ฐฉ๋ฒ•์„ ์ฐพ๋˜ ์ค‘ useStyles๋กœ์Šคํƒ€์ผ์„ ์ง€์ •ํ•œ๋‹ค๋Š” ์ ์„ ์•Œ์•„๋ƒˆ๋‹ค.  

 


โ– export ์—๋Ÿฌ

cannot be compiled under '--isolatedModules' because it is considered a global script file. Add an import, export, or an empty 'export {}' statement to make it a module. TS1208

ํ•ด๊ฒฐ๊ณผ์ • -> https://rrecoder.tistory.com/151


๐Ÿ“Œ  Material UI ์—์„œ  styled-componets ์‚ฌ์šฉํ•˜๊ธฐ

๊ฐ™์€ ์กฐ์ธ ์ด์•„๋จผ์Šค , ์–ดํ„ฐ๋จผ์Šค๊ป˜์„œ ํƒ๊ตฌํ•ด์ค€ ๋์— ์ข‹์€ ๋‚ด์šฉ์„ ์•Œ๊ฒŒ ๋˜์—ˆ๋‹ค! 

๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” material  UI์—์„œ ์„ค์ •ํ•œ ์Šคํƒ€์ผ์ด styled-components์—์„œ ์ง€์ •ํ•œ ์Šคํƒ€์ผ์„ ๋จน๋Š”๋‹ค 

styled  componets๊ฐ€ ์„ ์–ธ๋œ ํ›„์— -> materialUI์—์„œ  ์ธ๋ผ์ธ์œผ๋กœ ์„ ์–ธ๋˜๊ธฐ ๋•Œ๋ฌธ 

 

ํ•ด๊ฒฐ๋ฐฉ๋ฒ•  injectFirst

<StylesProvider injectFirst> ๋ฅผ ํ†ตํ•ด์„œ Material-UI → Styled-Components ์˜ ์ˆœ์„œ๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค.

ํ•˜๋‹จ ๋ธ”๋กœ๊ทธ์—์„œ injectFirst ์‚ฌ์šฉ๋ฒ•์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค .

 

๊ทธ๋ ‡๋‹ค๋ฉด materialUI์˜ useStyle์„ ๊ตณ์ด ์‚ฌ์šฉํ•œ๋Š ์ด์œ ๋Š”?

: useStyle ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด materialUI์˜ ํƒ€์ž…์„ ์•Œ์•„์„œ ์ถ”๋ก ํ•ด์ฃผ๋Š” ์žฅ์ ์ด ์žˆ๋‹ค. 

์ฐธ๊ณ :https://iamssen.medium.com/material-ui-%EC%99%80-styled-components-%EB%A5%BC-%EC%84%9E%EC%96%B4%EC%84%9C-%EC%93%B8%EB%95%8C-%EC%84%B8%ED%8C%85%ED%95%B4%EC%A4%98%EC%95%BC-%ED%95%98%EB%8A%94-%EA%B2%83-76570015a89

 

 


๐Ÿ“Œ IOS, FE, BE ํšŒ์˜

โ– ๊ฒŒ์‹œ๊ธ€ ์ €์žฅ ์‹œ ์ด๋ฏธ์ง€ ์ €์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๊ณ ๋ฏผ

ํŒŒ์ด๋กœ์˜ ์ •๋ฆฌ

 

1) ๊ฒŒ์‹œ๊ธ€์„ ์ €์žฅํ•  ๋•Œ ์ด๋ฏธ์ง€๋ฅผ ์ €์žฅ

์žฅ์ : ์ €์žฅ์†Œ ๋‚ญ๋น„๊ฐ€ ์—†์Œ 

๋‹จ์ : ์—๋Ÿฌ ์ฒ˜๋ฆฌ๋ฅผ ํ™•์‹คํžˆ ํ•ด์•ผ ํ•จ

 

2) ๊ฒŒ์‹œ๊ธ€ ์ž‘์„ฑ ์ค‘ ์ด๋ฏธ์ง€๋ฅผ ์„ ํƒํ•  ๋•Œ ์ด๋ฏธ์ง€ ์ €์žฅ

์žฅ์ : ๊ตฌํ˜„์ด ๋” ์‰ฝ๋‹ค

๋‹จ์ : ์ €์žฅ์†Œ ๋‚ญ๋น„

 

๐Ÿ™‚ ์ƒ๊ฐ๋ณด๋‹ค ์›น๊ณผ ๋ชจ๋ฐ”์ผ์—์„œ ์„ ํ˜ธํ•˜๋Š” ์‚ฌ์šฉ์ž UI ๊ฐ€ ๋‹ค๋ฅด๋‹ค๋Š” ๊ฑธ ๊นจ๋‹ฌ์•˜๋‹ค.

IOS : ๋งŽ์€ ๋ฒ„ํŠผ๋“ค์ด ์žˆ๋Š” ๊ฒƒ ๋ณด๋‹ค ํ•œ๊ฐ€์ง€ ๋ฒ„ํŠผ์œผ๋กœ ๊น”๋”ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค

web: ๊ตฌ์„ฑ์„ ์ž˜ ํ•˜๋ฉด ๋ฒ„ํŠผ์ด ๋Š˜์–ด๋‚˜๋Š” ๊ฒƒ์€ ํฌ๊ฒŒ ์ƒ๊ด€ ์—†๋‹ค ๋ผ๋Š” ๊ฒฐ๋ก ์ด ๋‚˜์„œ ์ผ๋‹จ ๊ฐœ๋ฐœ์„ ์ง„ํ–‰ํ•˜๋ฉฐ ์ถ”ํ›„์— ์ถ”๊ฐ€ํ•  ๊ฒƒ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค.

 

 

โ– ๋ฐฑ์—”๋“œ API ๋กœ์ปฌ 

์ด์ „๊นŒ์ง€๋Š” api ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด๋ณด๋ ค๋ฉด BE๋‹จ์—์„œ ๋ฐฐํฌ๋ฅผ ํ•ด์•ผ์ง€ api์š”์ฒญ ๊ณผ ์‘๋‹ต์ด ๊ฐ€๋Šฅํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— 

๋ฐฐํฌ ์ „๊นŒ์ง€๋Š” FE๋‹จ์—์„œ ์•Œ์•„์„œ mock๋ฐ์ดํ„ฐ๋ฅผ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•œํ›„ ๋ฐ๋ชจ ์ „์— ํ•ด๋‹น ๊ฐ’๋“ค์„ ๋ณ€๊ฒฝํ•ด์•ผ ํ–ˆ๋‹ค.

์ด ๊ณผ์ •์—์„œ FE๋‹จ์ด ๋งŒ๋“  mock๊ณผ BE์˜ API ๋ณ€์ˆ˜๋ช… ๊ฐ™์€๊ฒŒ ์ •ํ™•ํžˆ ํ˜‘์˜๋˜์ง€ ์•Š์œผ๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ด ๋ฒˆ๊ฑฐ๋กœ์›€์ด ์žˆ์—ˆ๋Š”๋ฐ 

 

BE๋‹จ์ด ๊ตฌํ˜„ ์ง„ํ–‰์ค‘์ด ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๋ฅผ ๋‚ด ์ปดํ“จํ„ฐ์—์„œ ๋„์ปค๋กœ ์˜คํ”ˆํ•  ์ˆ˜ ์žˆ๊ฒŒ ์„ค์ •ํ•ด๋†“์œผ์…”์„œ ๋‚ด๊ฐ€ ์›ํ• ๋•Œ๋งˆ๋‹ค ๋„์ปค๋กœ ์—ด์–ด์„œ ์‚ฌ์šฉํ–ˆ๋‹ค!

์ฆ‰ , ๋‚ด pc์—์„œ ์„œ๋ฒ„๋ฅผ ๋„์ปค๋กœ ๋Œ๋ฆฌ๊ณ , ๊ทธ ์•ˆ์— ์ž‡๋Š” db์— ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ์‘๋‹ต์„ ๋ฐ›์„ ์ˆ˜ ์ž‡/๋‹ค. 

๋ฐฑ์—”๋“œ ์—†์ด๋„ API ์š”์ฒญ์„ ํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค. ํŒŒ์ด๋กœ ์™€ ๋…ธ์„ ๊ฐ์‚ฌํ•ด์š” ใ… ใ… ใ… 

 

โ– Component๊ฐ„ ๊ด€๊ณ„๋„ ํšŒ์˜ 

์˜ค๋Š˜์€ ๊ฐ component๋“ค์˜ ๊ด€๊ณ„์— ๋Œ€ํ•œ ํšŒ์˜๋ฅผ ํ–ˆ๋‹ค.

์—ญ์‹œ๋‚˜ BE, IOS, FE ์˜ ๊ด€์ ์— ์ฐจ์ด๊ฐ€ ์žˆ์Œ์— ์žฌ๋ฐŒ์—ˆ๋‹ค.

BE: ์ผ๋‹จ BE๋Š” ์ € ํ•˜๋‚˜ํ•˜๋‚˜์˜ ์š”์†Œ๋ฅผ entity๋กœ ์นญํ•œ๋‹ค.   ๊ฐ ์—”ํ‹ฐํ‹ฐ์˜ 1:N ๊ด€๊ณ„๋ฅผ ๋ฏธ๋ฆฌ ์ƒ์„ธํžˆ ์ดํ•ดํ•˜๊ณ  ์„ฑ๋ฆฝํ•œ๋‹ค.

FE : View ์œ„์ฃผ๋กœ component๋ฅผ ๋‚˜๋ˆˆ๋‹ค. ์‚ฌ์šฉ์ž ์‹œ๋‚˜๋ฆฌ์˜ค์— ๋งž์ถฐ ์ฐจ๊ทผ์ฐจ๊ทผ ๊ด€๊ณ„๋ฅผ ์ดํ•ดํ•˜๊ณ  ์„ฑ๋ฆฝํ•œ๋‹ค.

IOS: FE์™€ ๋น„์Šทํ•˜๊ธด ํ•œ๋ฐ , ์šฉ์–ด๋‚˜ ๊ทธ๋Ÿฐ๊ฒƒ๋“ค์ด ์กฐ๊ธˆ์”ฉ ๋‹ค๋ฅด๋‹ค .

 

 


๐Ÿ“Œ 1์ฐจ PR ํ›„ ์ฝ”๋“œ๋ฆฌ๋ทฐ

1์ฐจ์ฝ”๋“œ๋ฆฌ๋ทฐ๋ฅผ ๋‹ค์‹œ ๋ณด๋‹ˆ ๊ทธ๋‹น์‹œ ๊ณ ๋ฏผ์ด ์ƒˆ๋ก์ƒˆ๋ก ๋– ์˜ค๋ฅธ๋‹ค.

๊ทธ ๋‹น์‹œ ๊ฐ€์žฅ ๊ณ ๋ฏผ๋๋˜ ๊ฒƒ์€

 

๐Ÿ“Œ ๋‹ค์–‘ํ•œ ์ข…๋ฅ˜์˜ ๋ฒ„ํŠผ์„ ํšจ์œจ์ ์œผ๋กœ ์„ ์–ธํ•˜๊ธฐ

์ฐธ๊ณ  - Material UI ์˜ Button์‚ฌ์šฉ์ค‘์ž…๋‹ˆ๋‹ค

 

ButtonGroup Component

์ž…๋ ฅ๋ฐ›๋Š” type์— ๋”ฐ๋ฅธ Button์„ ๊ฐ€์ ธ์˜ด

interface IButton {
  classes: IButtonType;
  name: string;
  color?: string;
  icon?: JSX.Element | undefined;
}

const ButtonGroup: FC<Prop> = ({ type, name, color = 'white', icon }: Prop) => {
  const classes = useButtonStyles();

  return {
    large: <ButtonLarge {...{ classes, name, color }} />,
    medium: <ButtonMedium {...{ classes, name, color }} />,
    smallFill: <ButtonSmallFill {...{ classes, name, color, icon }} />,
    smallBorder: <ButtonSmallBorder {...{ classes, name, color, icon }} />,
    mediumText: <ButtonMediumText {...{ classes, name, color, icon }} />,
    smallText: <ButtonSmallText {...{ classes, name, color, icon }} />,
  }[type] as JSX.Element;
};

export default ButtonGroup;

๊ทธ ๊ฐ๊ฐ์˜ Button๋“ค 

function ButtonLarge({ classes, name, color }: IButton) {
  return (
    <Button
      variant="contained"
      className={classes.buttonLarge}
      style={{
        backgroundColor: `${color}`,
        color: `${color === 'white' ? '#222' : '#fff'}`,
      }}
    >
      {name}
    </Button>
  );
}

์‚ฌ์šฉ ์‹œ

<ButtonGroup type={SMALL_FILL} name='์ด์Šˆ์ž‘์„ฑ' icon={<AddIcon style={{ fontSize: 16 }} />} />

์ด๋ ‡๊ฒŒ ํ•„์š”ํ•œ ์†์„ฑ๋“ค์„ ๋„ฃ์œผ๋ฉด ์งœ์ž”~ ๋ฒ„ํŠผ ๋“ฑ์žฅ

ํ•˜์ง€๋งŒ ์ด์นœ๊ตฌ๋“ค์˜ type์€ ๋ฌด์—‡์ผ๊นŒ์š”?

 

์•ž์„œ ๊ฐ Button ์ปดํฌ๋„ŒํŠธ๋“ค์ด ๋ฐ›์„ props๋Š” IButton ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋ฐ›๊ณ  ์žˆ๋Š”๋ฐ ๊ทธ์•ˆ์˜ classes ๋Š” IButtons๋ฅผ ๋ฐ›๊ณ  ์žˆ๋‹ค.

 

type IButtonType = ClassNameMap<
  | 'buttonLarge'
  | 'buttonMedium'
  | 'buttonSmallFill'
  | 'buttonSmallBorder'
  | 'buttonMediumText'
  | 'buttonSmallText'
>;

IButtonType์€ ๋ฐ”๋กœ ์ด๊ฒƒ!

 

useButtonStyles๋ฅผ ๋”ฐ๋กœ ์ด๋ ‡๊ฒŒ ๋งŒ๋“ค์—ˆ๊ณ 

import { makeStyles } from '@material-ui/core/styles';

const useButtonStyles = makeStyles(() => ({
  buttonLarge: {
    width: '340px',
    height: '64px',
    fontSize: '18px',
    borderRadius: '20px',
  },

Material UI์˜ Button component๋“ค์—๊ฒŒ ๊ฐœ๊ฐœ์ธ์˜ style ์†์„ฑ์„ ๋ถ€์—ฌํ•˜๊ธฐ ์œ„ํ•ด 

makeStyles๋ฅผ ์‚ฌ์šฉํ–ˆ๊ณ  ์ด style์€ ButtonGroup์—์„œ classes๋กœ ButtonCompoent ์—๊ฒŒ ์ „๋‹ฌ๋จ 

 

ButtonGroup 

const ButtonGroup: FC<Prop> = ({ type, name, color = 'white', icon }: Prop) => {
  const classes = useButtonStyles();

  return {
    large: <ButtonLarge {...{ classes, name, color }} />,
    medium: <ButtonMedium {...{ classes, name, color }} />, 
    //์ค‘๋žต
    }}
    
  function ButtonLarge({ classes, name, color }: IButton) {
  return (
    <Button
      variant="contained"
      className={classes.buttonLarge}
    >
      {name}
    </Button>
  );
}

์ด๋ ‡๊ฒŒ ์ „๋‹ฌ๋ฐ›์•„์„œ ์Šคํƒ€์ผ ์ง€์ • ๊ฐ€๋Šฅ!!!!


๐Ÿ“Œ TypeScript ์—์„œ styled-components ์— ์†์„ฑ ๋„˜๊ฒจ์ฃผ๊ธฐ

์Šคํƒ€์ผ ์ปดํฌ๋„ŒํŠธ์— img๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ๊ฐ€์ง€๊ณ  ์ž‡๋Š๋ฐ

 ๊ทธ ์•ˆ์— props๋กœ ๋„ฃ๊ณ  ์‹ถ์œผ๋ฉด img๊ฐ€ ๊ธฐ์กด์— ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์†์„ฑ ๋ช…์œผ๋กœ props๋ฅผ ๋„˜๊ฒจ์ฃผ์–ด์•ผ ํ•œ๋‹ค.

 

ProfileImg ์ปดํฌ๋„ŒํŠธ

interface ProfileImgProps {
  src: string;
  style: any;
}

const ProfileImg = ({ src, style }: ProfileImgProps): JSX.Element => {
  return <ProfileImgStyle {...{ src, style }}></ProfileImgStyle>;
};

export default ProfileImg;

const ProfileImgStyle = styled.img`
  width: ${({ style }) => `${style?.width}px`};
  height: ${({ style }) => `${style?.height}px`};
  border-radius: 70%;
`;

๊ฐ€๋ น ์˜ˆ์‹œ๋กœ ProfileImg์ปดํฌ๋„ŒํŠธ๊ฐ€ width๋ฅผ ์ง์ ‘ ๋ฐ›์•„์„œ ์ ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด 

ProfileImg ์˜ props๋Š” style, width๋“ฑ  ๊ธฐ์กด img๋ผ๋Š” ํ•จ์ˆ˜๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์†์„ฑ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

์‚ฌ์‹ค์ƒ styled.img ๋ผ๋Š”๊ฑด img๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ๋ถˆ๋Ÿฌ์™€ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ์•ˆ์—์„œ ๋ถ€๋ฅผ ์ˆ˜ ์žˆ๋Š” ์š”์†Œ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

 

์‚ฌ์šฉ์‹œ 

<ProfileImg style={{ width='20px', height='30px' }} />

์ด๋Ÿฐ๋Š๋‚Œ์„ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

 

๋Œ“๊ธ€