๐Ÿคฉ React JS๋กœ ์‚ฌ์šฉ์ž ์ง€์ • ๋ฒ„ํŠผ ๊ตฌ์„ฑ ์š”์†Œ ๊ตฌ์ถ•

24621 ๋‹จ์–ด webdevreactjavascriptcss
์ด๊ฒƒ์€ Custom UI Components With React ์‹œ๋ฆฌ์ฆˆ์˜ ๋งŽ์€ ๐Ÿ›Ž๏ธ ์ค‘ ์ฒซ ๋ฒˆ์งธ ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. ์ด ๊ฒŒ์‹œ๋ฌผ์—์„œ๋Š” React JS์—์„œ ๋‹ค์–‘ํ•œ ์†Œํ’ˆ๊ณผ ์Šคํƒ€์ผ์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ง€์ • ๋ฒ„ํŠผ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ด…๋‹ˆ๋‹ค.

์•„๋ž˜๋Š” ์ด ํŠœํ† ๋ฆฌ์–ผ์—์„œ ๋นŒ๋“œํ•  ๋ฐ๋ชจ์ž…๋‹ˆ๋‹ค.



โœ”๏ธ ๋ฒ„ํŠผ ์ปดํฌ๋„ŒํŠธ ์†Œํ’ˆ



์šฐ๋ฆฌ๋Š” ์ด ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ์†Œํ’ˆ์„ ๊ฐ€์ง€๋ฏ€๋กœ ์™ธ๋ถ€์—์„œ ์ด๋ฅผ ์‚ฌ์šฉ์ž ์ •์˜ํ•˜๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์†Œํ’ˆ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
  • btnColor - ์ด ์†Œํ’ˆ์€ ๋ฒ„ํŠผ์˜ ์ƒ‰์ƒ์„ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.
  • labelColor - ์ด ์†Œํ’ˆ์€ ๋ฒ„ํŠผ ๋‚ด๋ถ€์˜ ํ…์ŠคํŠธ ์ƒ‰์ƒ์„ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ white ์ด์ง€๋งŒ btnColor ์— ๋”ฐ๋ผ ์˜ฌ๋ฐ”๋ฅธ ๋Œ€๋น„๋ฅผ ๊ฐ–๋„๋ก ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • onClick - ์ด๊ฒƒ์€ onClick ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋ฒ„ํŠผ์— ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
  • type - ์ด ์†Œํ’ˆ์€ ๋ฒ„ํŠผ์˜ ์Šคํƒ€์ผ์„ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ’์€ outline | block | rounded ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. ์ด ์†Œํ’ˆ์ด ์ „๋‹ฌ๋˜์ง€ ์•Š์œผ๋ฉด ๋ฒ„ํŠผ์— ๊ธฐ๋ณธ ์Šคํƒ€์ผ์ด ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • ์Šคํƒ€์ผ - ์ด ์†Œํ’ˆ์—๋Š” ์™ธ๋ถ€์—์„œ ๋ฒ„ํŠผ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ œ๊ณตํ•˜๋ ค๋Š” ์‚ฌ์šฉ์ž ์ง€์ • ์Šคํƒ€์ผ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • disabled - ์ด ์†Œํ’ˆ์€ ๋ฒ„ํŠผ์ด ํ™œ์„ฑ ์ƒํƒœ์ธ์ง€ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.

  • ๐Ÿƒ๋ฒ„ํŠผ์˜ ๊ธฐ๋ณธ ์Šคํƒ€์ผ๋ง



    ๋ฒ„ํŠผ์— ๋ช‡ ๊ฐ€์ง€ ๊ธฐ๋ณธ ์Šคํƒ€์ผ์„ ๋ถ€์—ฌํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ button.module.css ํŒŒ์ผ์„ ์ƒ์„ฑํ•œ ๋‹ค์Œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฒ„ํŠผ์— ๋ช‡ ๊ฐ€์ง€ ๊ธฐ๋ณธ ์Šคํƒ€์ผ์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด btn ํด๋ž˜์Šค๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

    
    /* button.module.css */
    
    .btn {
        font-family: 'Ubuntu', sans-serif;
        position: relative;
        font-weight: 400;
        font-size: 1.3rem;
        line-height: 2;
        height: 50px;
        transition: all 200ms linear;
        border-radius: 4px;
        width: 240px;
        letter-spacing: 1px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        text-align: center;
        align-self: center;
        border: none;
        cursor: pointer;
        box-shadow: 0 12px 35px 0 rgba(16, 39, 112, .25);
        outline: 0;
        text-transform: capitalize;
    }
    


    ๐Ÿ’  ๋ฒ„ํŠผ ๊ธฐ๋Šฅ ์ปดํฌ๋„ŒํŠธ ์ƒ์„ฑ



    ์ด์ œ ์‚ฌ์šฉ์ž ์ •์˜ ๋ฒ„ํŠผ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ƒ์„ฑํ•  ํŒŒ์ผButton.js์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด ํŒŒ์ผ์—์„œ๋Š” styles ํŒŒ์ผ์—์„œ button.module.css๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ ๊ธฐ๋ณธ HTMLbutton ์š”์†Œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  btn์—์„œ styles ํด๋ž˜์Šค๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์†Œํ’ˆ์„ ๋ถ„ํ•ดํ•ฉ๋‹ˆ๋‹ค.

    //Button.js
    
    import React from 'react';
    import styles from './button.module.css';
    
    const Button = ({ children, onClick, btnColor = 'teal', labelColor, disabled, type, style, ...props }) => {
        return (
            <button
                className={styles.btn}
            >
                {children || 'label'}
            </button>
        );
    };
    
    export default Button;
    
    


    ์ด์ œ ์ด ํŒŒ์ผButton.js์—์„œ ๋‹ค์–‘ํ•œ ์œ ํ˜•์˜ ๋ฒ„ํŠผ์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ์Šคํƒ€์ผ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    
    //Button.js
    
        const commonStyles = {
            backgroundColor : btnColor,
            color           : labelColor || 'white'
        };
        const outlineStyles = {
            border          : `1px solid ${btnColor}`,
            color           : btnColor,
            backgroundColor : 'white'
        };
        const outlineHoverStyle = {
            color           : labelColor || 'white',
            backgroundColor : btnColor
        };
    
        const roundedStyle = {
            backgroundColor : btnColor,
            color           : labelColor || 'white',
            borderRadius    : '25px'
        };
        const disabledStyle = {
            cursor          : 'default',
            backgroundColor : btnColor,
            color           : labelColor || 'white',
            opacity         : 0.4
        };
        const blockStyles = {
            width  : '95%',
            margin : '0 auto'
        };
    


    ์—ฌ๊ธฐ์—๋Š” ๋ชจ๋“  ์œ ํ˜•์˜ ๋ฒ„ํŠผ์— ์ถ”๊ฐ€๋  btnColor์— ๋”ฐ๋ฅธ ๊ณตํ†ต ์Šคํƒ€์ผ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด์— ๋‹ค๋ฅธ ๋ชจ๋“  ์Šคํƒ€์ผ์€ ๋ฒ„ํŠผ์˜ type์— ๋”ฐ๋ผ ์กฐ๊ฑด๋ถ€๋กœ ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ outline ์œ ํ˜•์˜ ๊ฒฝ์šฐ ๋‘ ๊ฐ€์ง€ ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ๋Š” ๋ฒ„ํŠผ ์œ ํ˜•์ด ๊ฐœ์š”์ผ ๋•Œ ์ถ”๊ฐ€๋˜๋Š” ๊ธฐ๋ณธ outlineStyles์ด๊ณ  ๋‹ค๋ฅธ ๊ฒฝ์šฐ๋Š” ๋ฒ„ํŠผ ์œ„๋กœ ๋งˆ์šฐ์Šค๋ฅผ ๊ฐ€์ ธ๊ฐˆ ๋•Œ์ž…๋‹ˆ๋‹ค.

    ๋”ฐ๋ผ์„œ ํ˜ธ๋ฒ„ ์ƒํƒœ๋ฅผ ์ถ”์ ํ•˜๊ธฐ ์œ„ํ•ด ํ˜ธ๋ฒ„ ์Šคํƒ€์ผ์„ ์กฐ๊ฑด๋ถ€๋กœ ์ถ”๊ฐ€ํ•  state react hook๋กœ useState() ํ˜ธ๋ฒ„๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. Javascript ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ๊ธฐonMouseEnter ๋ฐ onMouseLeave๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ hover ์ƒํƒœ๋ฅผ ํ† ๊ธ€ํ•ฉ๋‹ˆ๋‹ค.

    ์ด์ œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์— ๊ฐ„๋‹จํ•œ switch ๋ฌธ์„ ์ถ”๊ฐ€ํ•˜์—ฌ ๋ฒ„ํŠผ ์œ ํ˜•์— ๋”ฐ๋ผ ์Šคํƒ€์ผ์„ ์กฐ๊ฑด๋ถ€๋กœ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.

    
    //Button.js
        let btnStyle;
        switch (type) {
            case 'rounded':
                btnStyle = roundedStyle;
                break;
            case 'block':
                btnStyle = blockStyles;
                break;
            case 'outline':
                if (hover) {
                    btnStyle = outlineHoverStyle;
                }
                else {
                    btnStyle = outlineStyles;
                }
                break;
            default:
                btnStyle = {
                    backgroundColor : btnColor,
                    color           : labelColor || 'white'
                };
                break;
        }
    
    
    


    ๊ทธ๊ฒŒ ์ „๋ถ€์ž…๋‹ˆ๋‹ค. ์ด์ œ ์†Œํ’ˆ์—์„œ ๋ฒ„ํŠผ์œผ๋กœ ์ „๋‹ฌ๋œ ๋ชจ๋“  btnStyle์™€ ํ•จ๊ป˜ ์ด style๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ๋ฒ„ํŠผ์— disabled ์†Œํ’ˆ์ด ์žˆ๋Š” ๊ฒฝ์šฐ ๋น„ํ™œ์„ฑํ™”๋œ ์Šคํƒ€์ผ๋„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ตœ์ข… ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

    
    //Button.js
    
    import React, { useState } from 'react';
    import styles from './button.module.css';
    
    const Button = ({ children, onClick, btnColor = 'teal', labelColor, disabled, type, style, ...props }) => {
        const [
            hover,
            setHover
        ] = useState(false);
        const toggleHover = () => {
            setHover(!hover);
        };
        const commonStyles = {
            backgroundColor : btnColor,
            color           : labelColor || 'white'
        };
        const outlineStyles = {
            border          : `1px solid ${btnColor}`,
            color           : btnColor,
            backgroundColor : 'white'
        };
        const outlineHoverStyle = {
            color           : labelColor || 'white',
            backgroundColor : btnColor
        };
    
        const roundedStyle = {
            backgroundColor : btnColor,
            color           : labelColor || 'white',
            borderRadius    : '25px'
        };
        const disabledStyle = {
            cursor          : 'default',
            backgroundColor : btnColor,
            color           : labelColor || 'white',
            opacity         : 0.4
        };
        const blockStyles = {
            width  : '95%',
            margin : '0 auto'
        };
        let btnStyle;
        switch (type) {
            case 'rounded':
                btnStyle = roundedStyle;
                break;
            case 'block':
                btnStyle = blockStyles;
                break;
            case 'outline':
                if (hover) {
                    btnStyle = outlineHoverStyle;
                }
                else {
                    btnStyle = outlineStyles;
                }
                break;
            default:
                btnStyle = {
                    backgroundColor : btnColor,
                    color           : labelColor || 'white'
                };
                break;
        }
        return (
            <button
                style={
    
                        disabled ? { ...commonStyles, ...btnStyle, ...disabledStyle, ...style } :
                        { ...commonStyles, ...btnStyle, ...style }
                }
                onMouseEnter={toggleHover}
                onMouseLeave={toggleHover}
                {...props}
                type="button"
                onClick={
    
                        !disabled ? onClick :
                        () => {}
                }
                className={styles.btn}
            >
                {children || 'button'}
            </button>
        );
    };
    
    export default Button;
    
    


    Here ๋ผ์ด๋ธŒ ๋ฐ๋ชจ๋ฅผ ๋ณด๊ณ  ์ด ๊ตฌ์„ฑ ์š”์†Œ์™€ ์ƒํ˜ธ ์ž‘์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    ์ด ํŠœํ† ๋ฆฌ์–ผ์„ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ์ด์™€ ๊ฐ™์€ ๋” ๋งŽ์€ ํŠœํ† ๋ฆฌ์–ผ์„ ๋ณด๋ ค๋ฉด ์ œ ๊ฐœ์ธ ๋ธ”๋กœ๊ทธsatishnaikawadi.me๋ฅผ ๋ฐฉ๋ฌธํ•˜์„ธ์š”. ์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค ๐Ÿ˜‡.

    ์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ