develop

props in styled-componenets, 템플릿 리터럴, 조건부 렌더링

crab. 2023. 1. 20. 16:10
  • 작업을 하다보면 스타일링을 할 때 주로 쓰는 방법이 몇 개 정해져 있다.
  • 자주 쓰는 방법이지만 쓸때마다 레퍼런스를 참고하고는 한다.
  • 이번에는 이런 방법들을 한 번에 모아서 정리해보기로 했다.

props in styled-components

  • css in js의 대표격인 styled-components의 장점 중 한가지는
  • jsx상에서 props를 주면 그거에 맞춰서 조건부로 스타일링을 할 수 있다는 점이다.
  • 이번에 요긴하게 사용한 부분은 유저의 선택에 따라 미리보기 화면에서 특정 버튼의 위치가 바뀌어야 하는 부분이었다.

  • 이걸 만들기 위해서는
// 유저의 선택에 따라 변하는 상태 rightState를 만든다.
const [rightState, setRightState] = useState("50px");

///////////////////

// 드롭다운 버튼에 아까 만든 상태의 setState를 onClick으로 할당한다.
<Menu isDropped={styleIsOpen}>
                <Ul>
                  <Li>
                    <LinkWrapper
                      href="#1-1"
                      onClick={() => {
                        setSelectedDropValue("오른쪽 하단");
                        setRightState("50px");
                        setBottomState("100px");
                      }}
                    >
                      오른쪽 하단
                    </LinkWrapper>
                  </Li>
                  <Li>
                    <LinkWrapper
                      href="#1-2"
                      onClick={() => {
                        setSelectedDropValue("중앙 하단");
                        setRightState("330px");
                        setBottomState("100px");
                      }}
                    >
                      중앙 하단
                    </LinkWrapper>
                  </Li>
                  <Li>
                    <LinkWrapper
                      href="#1-3"
                      onClick={() => {
                        setSelectedDropValue("왼쪽 하단");
                        setRightState("600px");
                        setBottomState("100px");
                      }}
                    >
                      왼쪽 하단
                    </LinkWrapper>
                  </Li>
                </Ul>
              </Menu>

///////////////////

// jsx문법으로 styled-components를 만들어주고
// props로 아까의 상태값을 넣어 준다.

<ButtonImg
                  src={`${nologo}`}
                  alt=""
                  right={rightState}
                  bottom={bottomState}
                />

///////////////////
// styled-components를 만들때 react의 props를 사용하듯이
// 받아온 상태값을 css에 사용하면 된다.
const ButtonImg = styled.img`
  position: absolute;
  background-blend-mode: overlay;
  right: ${props => props.right};
  bottom: ${props => props.bottom};
`;

///////////////////
// 추가로 만약 || 연산자를 응용한다면 props가 없을 때
// 기존의 값을 사용하게 할 수도 있다.
const ButtonImg = styled.img`
  position: absolute;
  background-blend-mode: overlay;
  right: ${props => props.right || "0px"};
  bottom: ${props => props.bottom || "0px"};
`;

jsx에 인라인으로 style 주는법

  • 작업을 하다보면 의도치 않게 inline style을 쓰는 경우가 종종 있다.
  • 사실 쓰는법은 단순한데 쓸때마다 그 방법을 까먹어서 구글링해서 쓰는게 싫어서 한번 정리해본다.
  • inline style은 선택순위가 매우 높다.
    • 따라서 color를 정할때 inline에는 red 선택자나 styled로 blue를 주면 color는 red가 된다.
  • 이번에 정리하면서 확실하게 알게된건데 inline style은 react에서 사용하지 않는것이 좋다.
    • 그 이유는
    • JSX는 React.createElement(...)로 통해 변환되고 모든 속성이 props 객체의 일부가 된다. 그러다 보니 style 부분의 비교는 항상 false가 나올 수밖에 없고({} === {} // false) 다시 렌더링될때마다 스타일 객체가 다시 계산되어 성능이 저하될 수 있다.
    • CSS 속성의 중복, 재사용성이 떨어진다.
    • 의사 클래스, 의사 요소, 미디어 쿼리, 키 프레임 애니메이션 같은 CSS의 기능을 온전하게 활용할 수 없다.
    • 앱의 규모가 커질수록 유지/보수가 어렵고 인라인 스타일이 많으면 코드 가독성도 떨어진다.
    • 리액트 공식 문서에서도 일반적으로는 추천하지 않는 방법이다.
  • 우선 그럼에도 피치 못하게 사용해야할 경우가 있을 수 있고..
    • 또 우선 정리하기로 했기에 한번 작성해보자면
  • inline style은 jsx문법에 의해 작성되므로 HTML에서는 class 가 jsx에서는 className인 것 처럼 camelCase로 작성해야 한다.
<ErrorMsg style={{ marginTop: "10px", marginBottom: "22px" }}>
  • 작성할때는 이렇게 style 속성값에 객체를 할당하는 방식으로 기입한다.
  • {{}} 이렇게 되는 이유는 style에 대한 value가 객체형태이기 때문이다.
  • 태그의 속성을 주고 싶을 때는 항상 "" 쌍따옴표로 감싼다.

템플릿 리터럴

  • 템플릿 리터럴 또한 단순하지만 쓸때마다 헷갈려서.. 이번에 확실하게 정리하고 가기로 했다.
  • 기존에는 문자열 연결시 ‘+’ 를 사용했지만
  • ES(ECMAScript)6에서 템플릿 리터럴(Template Literal)이라는 새로운 문자열 표기법을 도입했다.
  • 새로 도입된 템플릿 리터럴에서는 큰따옴표나 작은따옴표 대신 백틱문자(``)
    를 사용한다.
  • 기존 큰따옴표와 작은따옴표로 문자열을 작성하는 경우 불편한 점은 크게 2가지가 있었다.
    • 첫째는 문자열 내에서 큰따옴표와 작은따옴표를 출력하고 싶은 경우 각 따옴표 앞에 백슬래쉬()라는 이스케이프 시퀀스(Escape Sequence)를 입력해야 하는 점이다.
    • 두번째는 줄 바꿈을 할 때 줄 바꿈 코드(\n)도 입력해야 한다는 점인데.
  • 템플릿 리터럴을 사용한다면 그냥 쓰면 끝난다.
var message = " \"와 백슬래쉬 \n 불편해...\" ";
console.log(message);
/*
"와 백슬래쉬 
 불편해..." 
*/

var message = ` "와 백틱문자 
편해..." `;
console.log(message);
/*
"와 백틱문자
 편해..." 
*/
  • 또한 템플릿 리터럴의 가장 큰 장점은 템플릿 리터럴 내부에서는 변수를 사용할 수 있다는 것이다.
  • var, let, const로 정의한 값을 ${ }로 불러와 사용할 수 있다.
var name = "Jake";

//기존 방법
var message1 = "Hello, My Name is " + name +".";
console.log(message1); //Hello, My Name is Jake.

//템플릿 리터럴 적용
let message2 = `Hello, My name is ${name}`;
console.log(message2); //Hello, My Name is Jake.

const message3 = `${name} says,
 "I will use only 'Template Literal'."`;
console.log(message3);
/*
Jake says,
 "I will use only 'Template Literal'."
*/

인라인 스타일과 템플릿 리터럴의 응용

  • 전에 사용했던 코드를 다시 여기서 분석하면 좋을 것 같아 가져와 본다.
  • 상황은 부모 컴포넌트로 부터 받은 alarm이라는 객체에 있는 이미지를 background-image 값으로 jsx태그에 인라인으로 적용하는 상황이다.
<AlarmImg style={{ backgroundImage: `url(${alarm.imgUrl})` }}>

조건부 렌더링

  • 정말 정말 많이 쓰게 되는데 정리해보고 가자
  • 조건부렌더링은
    • &&
    • ?
  • 이 두가지를 주로 사용한다.
    • 물론 if문을 사용할 수 있지만 코드의 길이가 길어진다..

?의 경우

function Hello({ color, name, isSpecial }) {
  return (
    <div style={{ color }}>
      { isSpecial ? <b>*</b> : null }
      안녕하세요 {name}
    </div>
  );
}
  • isSpecial값이 true라면 <b>*</b>를, 그렇지 않다면 null을 보여주도록 했다.
  • 참고로 JSX 에서 null, false, undefined 를 렌더링하게 된다면 아무것도 나타나지 않게 된다.
  • 지금은 내용이 달라지는게 아니라, 단순히 특정 조건이 true이면 보여주고, 그렇지 않다면 숨겨주고 있는데,
  • 이러한 상황에서는 &&연산자를 사용해서 처리하는 것이 더 간편하다

&&의 경우

  • JavaScript에서 true && expression은 항상 expression으로 평가되고 false && expression은 항상 false로 평가된다.
  • 따라서 && 뒤의 엘리먼트는 조건이 true일때 출력이 된다.
  • 조건이 false라면 React는 무시하고 건너뛴다.
function Hello({ color, name, isSpecial }) {
  return (
    <div style={{ color }}>
      {isSpecial && <b>*</b>}
      안녕하세요 {name}
    </div>
  );
}
  • falsy 표현식을 반환하면 여전히 && 뒤에 있는 표현식은 건너뛰지만 falsy 표현식이 반환된다는 것에 주의해야한다.
  • 아래 예시에서는, <div>0</div>이 render 메서드에서 반환된다.
render() {
  const count = 0;
  return (
    <div>
      {count && <h1>Messages: {count}</h1>}
    </div>
  );
}

출처

https://www.daleseo.com/react-styled-components/

https://goddino.tistory.com/282

https://velog.io/@zero_mountain/ReactStyle-인라인스타일에-관하여

https://velog.io/@hyuns/React-JSX-qmc0zr6s

https://code-masterjung.tistory.com/68

https://corini.tistory.com/entry/리액트React-학습자를-위한-기초지식-템플릿-리터럴-구조분해-할당

https://pang2h.tistory.com/116

https://eomtttttt-develop.tistory.com/211

https://react.vlpt.us/basic/06-conditional-rendering.html

https://learnjs.vlpt.us/useful/03-short-circuiting.html

https://ko.reactjs.org/docs/conditional-rendering.html