Udemy - React완벽가이드

리액트 컴포넌트 스타일링

Hanachoi 2023. 3. 15. 17:05

#동적 인라인 스타일 설정하기

  • 리액트에서 컴포넌트별로 css파일을 나눠서 스타일링을 하더라도 사실 이 css는 전역적으로 적용이 되는 애들이다. 하나의 컴포넌트에만 국한되지 않고 전체적으로 동일한 class나 태그라면 스타일이 적용되어 버린다.
  • 현재 스타일링에서는 Add Goal 버튼을 클릭하면 아무런 내용이 없는 박스가 하나 생긴다. 이부분을 수정해 경고창을 날려주도록 해보자

  • <CourseInput>컴포넌트에 조건문을 하나 넣어준다. 폼이 제출될때마다 발생되는 일이기 때문에 해당 함수로 가서 조건문을 넣어준다. 
  • .trim() 메소드는 생기는 공백을 제거해준다.
  • enteredValue.trim().length 가 0이라면 어떤 값도 들어오지 않았음을 의미한다 (입력값이 없음). 그럼 바로 return을 해주면 다음 줄에 있는 props.onAddGoal 코드가 작동되지 않는다. return이 반환되면 함수의 실행은 그냥 중단되기 때문이다. 

  • 하지만 이렇게 하면 어떤 값을 입력하고 Add Goal 버튼을 누르면 작동은 하지만, 입력하지 않고 버튼을 눌렀을때 어떤 사용자 피드백도 나오지 않는다. 
  • state를 사용해서 이 상태에 대한 업데이트를 해줄 수 있다.
  • 사용자가 유효한 값을 입력했는지를 확인하는 state를 만들어준다. 그래서 이 값은 true/false의 불리안 값으로 들어가게 된다. 처음에는 사용자를 신뢰한다는 전제하에 true값을 넣어준다. 

  • 그리고 if 조건문으로 돌아가 사용자가 입력을 하지 않았다면 false로 값을 바꿀 수 있게 setIsValid함수를 넣어준다.

  • 사용자가 값을 입력하지 않아서 false가 된다면 나타나는 스타일을 적용해준다. 
  • style을 인라인으로 바로 넣어주게 되면 값으로 객체가 들어가야하니까 {{}} 더블로 중괄호가 들어가게 된다. 그안에는 다시 조건문을 넣어준다. color를 설정해줄때,  입력값이 유효하지 않다면 (!isValid)라면 빨간색, 아니라면 검정색이 되도록 조건문을 작성한다. 

  • input 박스도 값이 들어오지 않았다면 빨간색으로 border를 처리해주도록 값을 넣어준다. style에서 css를 넣어줄때는 css에서 사용하는 이름을 그대로 쓰되, 카멜케이스를 적용해서 써준다. 

  • 하지만 이렇게 인라인스타일을 적용하면 항상 css가 최우선순위에 들어가기 때문에 오버라이드 될 수 있다. 그래서 기존에 만들어서 import했던 css파일의 내용이 적용되지 않는 경우가 발생해서 인라인스타일은 사용하지 않는게 좋다. 
  • 사용자가 새롭게 칸에 무언가를 입력하면 적용됬던 스타일이 원래대로 돌아오도록 아래처럼 if문을 넣어준다. 

 

 

 

#동적으로 CSS 클래스 설정하기

  • css를 설정할 수 있는 다른 방법으로는 class를 설정해주고 invalid할때만 이 css가 작동하도록 하는 것이다.
  • css파일에 .invalid라는 클래스를 설정해준다. [.form-control.invalid]에서 빈칸이 존재하면 안된다. 

  • 동적으로 클래스를 설정하기 위해서는 {}를 써줘야한다. 그냥 ' ' 로 스트링을 넣은 경우는 하드코딩이 되어있는 경우다.
  • 클래스 이름이 'form-control'이 될수도 'form-control invalid'가 될수도 있는데 그건 useState에서 쓴 isValid에 따라서도 다르고 어떤 이름을 쓰는 상황인가에 따라서도 다를 수 있다. 
  • 백틱(` `)을 사용해 조건문을 같이 className에 넣어줄 수 있다.

  • 이렇게 동적으로 class를 넣어줘서 css를 작동할 수 있게 됬다! 

 

#Styled Componenets 소개

  • 앞서 말한대로, css스타일은 하나의 컴포넌트에만 국한시킬수가 없다. 물론 선택자(selector)를 잘 설정해서 구분지으면 되겠지만, 많은 개발자가 협업을 하는 형태에서는 선택자가 겹칠 수도 있고 응용프로그램에서의 다른 위치에서 사용될 수도 있다.
  • 이를 피하기 위한 첫번째 방법으로 styled componenets 패키지를 사용하는 것이다. 
  • https://styled-components.com/ 를 따라 npm에 install 해준다.
  • 현재 만들어진 버튼 컴포넌트에 적용시켜보자
  • 기본적으로 import 되어있는 css 파일을 지워준다. 그리고 styled를 import 해준다.

  • button을 다시 만들어준다. 이 문법은 태그드 템플릿 리터럴로, 자바스크립트 프로젝트에서 사용할 수 있는 애다. ㅠ button은 styled객체의 메소드이다. 뒤에는 백틱을 쓴다.

  • styled 뒤에 붙은 button 메소드가 새로운 button 컴포넌트를 반환해준다. 
  • styled는 모든 html에 대한 메소드를 가지고 있다. 
  • 백틱 안에 css디자인을 넣어주면된다. 하지만 얘는 class를 따로 지정하지 않기때문에 조금 다르게 css를 넣어준다.

  • 버튼에 대한 기본적인 css는 선택자 없이 넣어주고 가상선택자(peudo code)는  &으로 바꿔준다.
  • 원래는 button 컴포넌트가 전체적으로 태그를 감싸주는 형식이었지만, 이제는 이렇게 만든 button 메소드가 내부적으로 사용되고 있는 것이다.
  • 개발자도구로 elements를 살펴보면 button에 이상하게 생긴 class가 들어간걸 볼 수 있다. 얘네느 styled 컴포넌트가 생성한 클래스 이름이다
  • 이렇게되면 모든 클래스는 고유한 이름을 가지기 때문에 다른 컴포넌트에 영향을 주지 않게 된다!

 

#styled components & 동적 props

  • 우리는 기본적으로 한 파일에 한 컴포넌트만을 만들어왔다. 일반적으로는 그렇게 사용하지만 하나의 파일이 두개 이상의 컴포넌트를 가질 수도 있다.
  • courseInput 컴포넌트에 또 다른 styled component를 추가해준다. css는 백틱안에 동일하게 넣어주면 된다.
  • 더 상세하게 목표하기 위해 [.form-control input] 처럼 작성했던 부분은 선택자를 지우고 그 자리에 &을 넣어주면 된다. 

  • 그리고 원래 <div>가 있던 자리를 <FormControl>로 바꿔주면 된다.

  • 하지만 이렇게 만들어 줬을때, 원래 설정했던 invalid 할때의 css가 적용되지 않는다. 이 부분을 수정하기 위해서 formcontrol에 className을 넣어서 해주거나 props를 전달해줄 수 있다.
  • className을 사용한 경우 isValid가 유효한지 체크하고 유효하지 않다면 invalid라는 문자열이 나오도록 넣어주면 된다. 

  • Formcontrol에 props를 넣어준다. 사용자가 값을 입력하면 true로 전달이 되고 입력하지 않았으면 false로 전달이된다. 이때 css를 다시 위에서 만든 styled component에 동적으로 넣어줄 수 있다. 

  • 백틱 사이에는 ${}를 쓸 수 있다는 사실을 잊지말자. props를 동적으로 받아와 여기에 isValid가 true일때와 false일때의 css를 각각 다르게 적용해줄 수 있다. 

 

 

# Styled components & 미디어쿼리

  • 미디어쿼리를 적용해주는 방법은 간단하다. 그냥 원래처럼 @media로 원하는 스타일을 적용시켜주면 된다.
  • button의 크기가 768px이하일때 버튼의 크기가 꽉 차도록 해줬다.

  • 그리고 기존의 버튼에는 width를 추가해서 100% 기본 설정을 해준다.  원래의 화면에서는 그냥 원래만큼의 크기를 차지하지만 크기가 작아지면 크기가 더 작아지도록 해줬다. 

 

#CSS 모듈 사용하기

  • 어떤 스타일을 사용하던지는 선호도에 따른 차이지만, css를 따로 파일로 나눠서 관리하고 싶다면 Module css를 사용하면 된다. 기본적으로 리액트에서 지원하고 있다.
  • 다시 JSX 문법을 사용할 것이기 때문에 react를 import 해준다. 
  • css를 import 할때는 classes나 styles를 import 해주고 뒤에 css 파일을 붙여준다.

  • 사실 코드를 변환하기 위해서는 css 파일의 이름을 바꿔줘야 한다.

  • 원래 기존에 주석처리했던 Button 컴포넌트를 다시 활성화 시켜준다. 그리고 className을 동적으로 바꿔준다.

  • module css가 하는일은 궁극적으로 css클래스나 css파일을 가지고 그 클래스 이름을 고유하게 바꿔주는 것이다.
  • import하는 css 파일을 모두 unique 하게 만들어준다. 중복되지 않도록!
  • 기존의 css 코드는 변경하지 않아도 된다.  

  • 모듈 css를 사용하면 이렇게 알아서 고유한 class를 만들어준다. 그래서 우리가 사용하는 컴포넌트만 scope 할 수 있도록 도와준다. 

 

#CSS 모듈을 사용한 동적 스타일

  • 똑같이 css 이름을 module을 넣어주고 import 해준다. 
  • 기존에 썼던 컴포넌트는 지우고 다시 <div>로 변경해준다. 이때 form-control이라는 이름을 쓰기 위해서는 [ ] 괄호가 필요하다.  중간에 - 대쉬가 있으면 원래는 . 으로 부를 수 없다. 
  • 스트링은 자바스크립트 객체에서 유효한 키이기 때문에 이렇게 사용해주면 접근이 가능하다.

  • 이렇게까지 하면 스타일은 여전히 동일하게 적용되지만 invalid 할때의 스타일이 바뀌지 않는다. 이걸 적용시켜주기 위해서 다시 리터럴 템플릿을 사용하면 된다. 

  • 미디어 쿼리를 적용해주기 위해서는 다시 선택자가 필요하기 때문에 선택자를 넣어준다 

< button>컴포넌트