yarn add styled-components
기본적으로 이 명령어로 패키지를 설치할 수 있다.
import styled from "styled-components";
/.../
const StBox = styled.div`
이 안에 css를 넣는다.
`
const App = () => {
return <StBox>박스</StBox>;
};
export default App;
styled component의 가장 효율적인 이유 중에 하나는 조건부 스타일링 가능하다는 거다.
CSS-in-JS 방식으로, css문을 이용해 if문이나 switch문을 이용해 조건에 맞는 css를 간단하게 구현할 수 있다는 점이다.
const ButtonWrapper = styled.button`
${({ theme })=>{
switch (theme){
case "link" :
return css`
padding : 0;
color : grey;
background : none;
width : fit-content;
`
case "secondary":
return css`
display : flex;
justify-content : center;
align-item : center;
flex-direction : wrap;
gap : 15px;
`;
}
}}
`
예를 들어보자면 이런식으로 쓸 수 있다는 것이다. (실제 매니저님이 실무에서 쓰시는 코드 일부 캡쳐해서 올린다.)
setState(number + 1); //....(1)
setState((previousState) => previousState + 1)); //....(2)
(1)의 경우 리액트 라이브러리는 한꺼번에 모아 최종적으로 처리하게 된다.
(2)의 경우에도 똑같이 모아 처리하지만, 순차적으로 처리하기 때문에, 모든 함수형 업데이트가 실행된다.
useEffect(()=>{
// 실행하고 싶은 함수
}, [의존성배열])
의존성배열 -> 이 안에 값을 넣으면 해당 값이 바뀔때만 useEffect가 실행된다.
if 아무것도 넣지 않았다면, 처음에 딱 한번만 실행되고, 그 후 값이 바뀌어도 실행되지 않는다.
( console.log 찍어보면 해당값 자체는 바뀐다!)
import React, { useEffect } from "react";
const App = () => {
useEffect(()=>{
// 기존의 구역
return ()=>{
// clean up 구역
}
}, [])
return <div>hello react!</div>
};
export default App;
useRef의 목적은 딱 두개이다.
import { useEffect, useRef } from "react";
import "./App.css";
function App() {
const idRef = useRef("");
// 렌더링이 될 때
useEffect(() => {
idRef.current.focus();
}, []);
return (
<>
<div>
아이디 : <input type="text" ref={idRef} />
</div>
<div>
비밀번호 : <input type="password" />
</div>
</>
);
}
export default App;
리렌더링의 발생 조건?
1. 컴포넌트에서 state가 바뀌었을 때
2. 컴포넌트가 내려받은 props가 변경되었을 때
리액트에서 리렌더링이 많이 일어난다는 건 그렇게 좋은 일은 아니다.
최적화(optimization)은 불필요한 렌더링이 발생하지 않도록 한다.
React.memo()
사실 React.memo는 진짜 별거 없다.
마지막에 export부분에서
export default React.memo(Box1);
export default React.memo(Box2);
export default React.memo(Box3);
정도 생각하면 되겠다.
-> 컴포넌트 메모이제이션이라고 한다.
useCallback()
함수형 컴포넌트를 쓸 때, 콜백 함수를 props로 자식 컴포넌트로 내리는데, 이때 컴포넌트 메모이제이션을 하더라도, 리렌더링이 되기 마련이다.
-> 이때 함수 안 함수도 다시 만들어졌다고 생각하면서 props로 새로운 값을 전달 받았다고 여겨진다. 이는 새로운 주솟값으로 연결되고, 이런 리렌더링을 막기 위해서 useCallback()을 쓴다.
useMemo()
import React, { useEffect, useState } from "react";
function ObjectComponent() {
const [isAlive, setIsAlive] = useState(true);
const [uselessCount, setUselessCount] = useState(0);
const me = {
name: "Ted Chang",
age: 21,
isAlive: isAlive ? "생존" : "사망",
};
useEffect(() => {
console.log("생존여부가 바뀔 때만 호출해주세요!");
}, [me]);
return (
<>
<div>
내 이름은 {me.name}이구, 나이는 {me.age}야!
</div>
<br />
<div>
<button
onClick={() => {
setIsAlive(!isAlive);
}}
>
누르면 살았다가 죽었다가 해요
</button>
<br />
생존여부 : {me.isAlive}
</div>
<hr />
필요없는 숫자 영역이에요!
<br />
{uselessCount}
<br />
<button
onClick={() => {
setUselessCount(uselessCount + 1);
}}
>
누르면 숫자가 올라가요
</button>
</>
);
}
export default ObjectComponent;
useEffect를 써서 의존성 배열에 me를 넣어서, me 가 변할 때만 콘솔이 찍히겠금 해봤는데, 필요없는 숫자 count 버튼이 눌려도, 계속 콘솔이 찍힌다.
이럴 때 값에 대한 메몰이제이션을 이용할 수 있다.
const me = useMemo(() => {
return {
name: "Ted Chang",
age: 21,
isAlive: isAlive ? "생존" : "사망",
};
}, [isAlive]);
me 객체 자체를 useMemo함수로 감싸주면, 맨 처음 할당했을 때의 그 값을 특별한 메모리에 저장한다. 이 값과 비교해서 변함이 없다면 불필요한 렌더링을 줄일 수 있는 것이다.