프로그래밍/프로젝트

유데미 강의 React 완벽 가이드의 두 번째 프로젝트

나도 오늘부터 개발자?! 2023. 4. 24. 17:08

이번 미니 프로젝트는 CSS에 관한 내용으로 리액트에서는 CSS를 컴포넌트 형태로 분리해서 적용한다고 하더라도 전역으로 설정되기 때문에 모든 컴포넌트에서 해당 CSS에 접근이 가능합니다.

 

그래서 CSS를 각 컴포넌트 단위로 지정하여 설정할 수 있는 방법에 대해 배우는 프로젝트를 진행 합니다.

 

CSS를 컴포넌트에 맞춰 지정하는 방법으로 가장 유명한 두 가지 방법을 설명하기 앞서 사용자에게 입력 값을 받을때 사용자가 입력조건에 맞춰 올바르게 입력 하였는지 유효성 검사를 하는 방법과 CSS를 동적으로 설정하는 방법에 대해서 이야기를 하고 넘어가도록 하겠습니다.

 

유효성 검사를 해야하는 이유는 오류를 방지하기 위함이며, 확인을 하지 않으면 추후에 문제를 야기할 수 있습니다.

const CourseInput = props => {
  const [enteredValue, setEnteredValue] = useState('');
  const [isValid, setIsValid] = useState(true);

  const goalInputChangeHandler = event => {
    setEnteredValue(event.target.value);
  };

  const formSubmitHandler = event => {
    event.preventDefault();
    
    if(enteredValue.trim().length === 0) {
      setIsValid(false);
      return;
    }
    props.onAddGoal(enteredValue);
  };

  return (
    <form onSubmit={formSubmitHandler}>
      <div className="form-control">
        <label style={{color: !isValid ? 'red' : 'black'}}>
        Course Goal</label> 
        <input 	
        type="text" 
        onChange={goalInputChangeHandler} 
        style={{backgroundColor: !isValid ? 'red' : 'white'}}
        />
      </div>
      <Button type="submit">Add Goal</Button>
    </form>
  );
};

위의 코드에서 사용자가 데이터를 입력 했는지 if문을 통해 확인한 뒤 State를 사용하여 데이터가 없으면 label 태그와 input 태그의 색을 삼항연산자를 통해 빨간색으로 변경시켜 주는 로직 입니다.

 

그 중 <label style={{color: !isValid ? 'red' : 'black'}}> 과 input style={{backgroundColor: !isValid ? 'red' : 'white'}}안에 style을 보면 삼항연산자를 이용한 동적으로 CSS를 작성한 내용이 있습니다.

 

   

CSS를 각 컴포넌트에 맞춰 지정하는 방법

1. styled components 사용하기

https://styled-components.com/

 

사용법 : styled components 설치 후 적용할 컴포넌트 안에 아래와 같이 변수 = styled.원하는 태그``; 로 작성한다

스타일은 ``템플릿 리터럴 안에 작성하면 됩니다 

import React, { useState } from 'react';

import styled from 'styled-components';
import Button from '../../UI/Button/Button';
import './CourseInput.css';

const FormControl = styled.div`

  margin: 0.5rem 0;

& label {
  font-weight: bold;
  display: block;
  margin-bottom: 0.5rem;
}

& input {
  display: block;
  width: 100%;
  border: 1px solid #ccc;
  font: inherit;
  line-height: 1.5rem;
  padding: 0 0.25rem;
}

& input:focus {
  outline: none;
  background: #fad0ec;
  border-color: #8b005d;
}

&.invalid input {
  border-color: red;
  background-color: red;
}

&.invalid label {
  color: red;
}
`;

const CourseInput = props => {

  return (
    <form onSubmit={formSubmitHandler}>
      <FormControl className={!isValid && 'invalid'}>
        <label>Course Goal</label>
        <input 
        type="text" 
        onChange={goalInputChangeHandler} 
        />
      </FormControl>
      <Button type="submit">Add Goal</Button>
    </form>
  );
};

export default CourseInput;

// styled-components를 적용하지 않는 css
.form-control {
  margin: 0.5rem 0;
}

.form-control label {
  font-weight: bold;
  display: block;
  margin-bottom: 0.5rem;
}

.form-control input {
  display: block;
  width: 100%;
  border: 1px solid #ccc;
  font: inherit;
  line-height: 1.5rem;
  padding: 0 0.25rem;
}

.form-control input:focus {
  outline: none;
  background: #fad0ec;
  border-color: #8b005d;
}

.form-control.invalid input {
  border-color: red;
  background-color: red;
}

.form-control.invalid label {
  color: red;
}

 

2. css 모듈 사용하기

https://create-react-app.dev/docs/adding-a-css-modules-stylesheet/

 

사용법 : CSS 파일의 이름을 [name].module.css로 변경 합니다. 그리고 사용할 컴포넌트에

import styles from './[name].module.css'; 임포트 해준 사용하려는 태그 뒤에 ClassName = {styles.[css name]}로 작성하면 됩니다. 

주의: 만일 사용하려는 스타일 이름에 "-" 하이픈이 들어가면 ClassName = {styles['css name']} 으로 작성해야 합니다 (대괄호 안에 작성하세요)

 

import React, { useState } from 'react';

import Button from '../../UI/Button/Button';
import styles from './CourseInput.module.css';


const CourseInput = props => {
  const [enteredValue, setEnteredValue] = useState('');
  const [isValid, setIsValid] = useState(true);


  return (
    <form onSubmit={formSubmitHandler}>
      <div className={`${styles['form-control']} ${!isValid && styles.invalid}`}>
        <label>Course Goal</label>
        <input 
        type="text" 
        onChange={goalInputChangeHandler} 
        />
      </div>
      <Button type="submit">Add Goal</Button>
    </form>
  );
};

export default CourseInput;
import React from 'react';

// import './Button.css';
import styles from './Button.module.css';

const Button = props => {
  return (
    <button type={props.type} className={styles.button} onClick={props.onClick}>
      {props.children}
    </button>
  );
};

export default Button;