(2023/08/30)
ReactDOM
=>Web App
개발에 사용한다.React Native
=>Mobile App
개발에 사용한다.
Strict Mode
는 각Component
의 기능을 2번 호출하여, 순수 함수의 규칙을 위반하는Component
를 찾는 데 도움을 준다.
👉Root Component
에<StrictMode>
로 감싸서 사용한다.
👉Strict Mode
는 배포에 영향을 미치지 않는다.
Rendering Trigger
Component
가 최초 실행될 때 Rendering
을 지시한다.Rendering
을 지시한다.Components Rendering
Component
가 정의된 Function
이 (다시) 실행된다.DOM Commit
ReactDOM
의 JSX
가 실제 DOM
에 Mount
된다.Mount
된 이후, Callback Function
으로 인해 Side Effects
가 발생한다.Bronwser Painting
Browser
를 그리는 단계이다.React.memo
를 통해 props
가 변경되지 않은 Component
가 리렌더링
되는 것을 방지한다.마크업을 반환하는 JavaScript 함수
👉 Atomic Component
는 상태를 가지지 않는 것이 좋다.
Component
의return
전에는 불필요한 코드를 배치하지 않는다.
👉 순수 함수- 함수로 정의되었지만,
함수()
처럼 실행하지 않고<이름></이름>
또는<이름 />
으로 실행한다.
👉 하나의 매개변수인props
만 받는다.
선언된
Component
내부에 다른Component
가 선언되면 안 된다.
👉Component
를 파일별로 구분하여 최상위 수준에 작성한다.
Component
의 네이밍은 항상Pascal Case
로 한다
👉 소문자로 시작하면,Function
으로 인식한다.
createRoot
로Component
를 담을 요소를 생성한다.createRoot.render()
로render
한다.Component
로 구성된 요소 안에text
를 넣으려면props.children
을 사용하여rendering
한다.
export 함수
👉 불러오기
import { 이름 } from '경로'
export default 함수
👉 불러오기
import 이름 from '경로'
- 일반적으로 내보낼
Component
가 하나인 경우에 기본 내보내기를 사용한다.- 이름으로 내보내기와 기본 내보내기는
{ }
사용 여부의 차이가 있다.
React API
로 작성하면 코드가 복잡하기 때문에 JavaScript
의 확장인 JSX
를 이용하여 HTML
을 마크업한다.
Browser
는JSX
는 읽을 수 없다.
👉Vite
와 같은 도구를 이용하여 표준JavaScript
로 변환해야Browser
가 읽을 수 있다.
- 형제 요소가 있다면,
<div>
또는<React.Fragment>
와 같은 래퍼를 꼭 써서 내보내야 한다.
👉 감싼 요소를 렌더링하지 않고자 할 때,<React.Fragment>
를 사용한다.
👉<React.Fragment>
는<>
로 쓸 수 있다.- 한번 연
tag
는 반드시 닫아줘야 한다.
👉<img>
와 같이 닫는 태그가 없는 요소는<img />
처럼 닫아줘야 한다.- 속성의 이름은
Camel Case
로 작성한다.
👉aria-
,data-
는-
를 사용한다.- 변수에 할당된 것과 같이 동적으로 생성된 문자 값을 전달할 때에는
{ }
안에 삽입한다.
👉JavaScipt
의 객체는{ }
로 표현되기 때문에,JavaScript
의 객체를 삽입할 때에는{{ }}
이중 중괄호가 된다.
독립적인 비공개 데이터
상태는 최소한으로 만들어서 관리한다.
- 상태를 여러가지를 만들기보다 파생된 상태를 만들어서 처리한다.
- 상태를 그룹으로 묶어서 관리할 수도 있다.
React
의 상태는 Snapshot
같아서,
Rendering Trigger
로 인해 새로 리렌더링
되지 않는 이상 상태 변수의 값은 절대 변경되지 않는다.
👉 useState
Hook
을 사용하여 상태 변수의 값을 변경시켜 리렌더링되도록 한다.
상태변수
는 같은상태변경함수
이더라도 각Component
마다 독립적으로 동작한다.
👉 같은상태변수
를 다른Component
와 공유하고 싶을 때에는 상위 요소에상태변수
를 전달한다.상태변수
는 상위Component
에서 접근/조작할 수 없다.
이벤트로 상태를 변경하고자 할 때는 set 함수를 함수에 담아서 전달해야 한다.
그렇지 않으면 무한 리렌더링 하게 된다.
value
를 설정했을 경우
onChange
Handler
로value
를 변경할 수 있다.defaultValue
로초깃값
을 설정하여 변경할 수 있다.
👉defaultValue
를 사용하면 명령형이기 때문에 외부Event
와 연결하기에 어려움이 있다.readOnly
를 설정하여읽기전용
으로 만들 수 있다.
객체와 배열인 상태는 원본이 훼손되지 않도록 복사해서 처리한다.
const [상태변수, 상태변경함수] = useState(초깃값);
/* 초깃값을 시작으로 상태변경함수가 실행될 때마다 상태변수가 리렌더링된다. */
/* useState Hook은 실행되면 상태변수와 상태변경함수를 요소로 가지는 배열이 반환되기 때문에,
배열 구조 분해 할당을 이용하여 변수에 상태변수와 상태변경함수를 할당한다. */
상태변경함수(상태변수 + 1); // 상태변경함수의 인수를 전달하여 상태변수의 값을 변경시킨다.
상태변경함수
는set~
으로 시작한다.상태변경함수
의 인수로 업데이트 함수를 전달해서 한 번의Rendering
에 업데이트를 중첩시킬 수 있다.
.map()
등을 사용하여 배열을 렌더링하는 경우key
설정이 필요하다.
👉cypto.randomUUID()
를 이용하여random key
를 생성할 수 있다.
👉key
값은 고유해야 하나, 다른 배열의key
와는 동일해도 된다.
👉render
할 때마다key
가 변경되면render
할 때마다 새로 생성하기 때문에, 성능 저하가 있다.
👉key
는 최상위 요소에 붙인다.
👉key
는 블록 내에서 한번만 사용한다.
Component
의 props
에 함수를 넘겨주고, JSX
요소의 속성으로 Event
와 함수를 연결해준다.
function GotoButton({함수이름}) {
return <button onClick={함수이름}>버튼</button>
}
상위
Component
에 연결된 경우에는 상위Component
의 속성에서 정의한다.
수많은 Event
를 일일이 전달하기에는 번거롭기 때문에, 상위 Component
에서 Event Function
을 정의하고, 하위 Component
에서는 Spread Syntax
를 (...
)를 이용하여 Event
를 적용한다.
Side Effect
는 일반적으로 Event Handler
연결에 속한다.
Event Handler
는rendering
되는 동안 실행되지 않기 때문에 순수할 필요가 없다.
useEffect
Hook
내부에 있는 코드는DOM Commit
단계 이후에 실행된다.
👉 어떤 코드를 작성하더라도Rendering
에 영향을 주지 않기 때문에 순수 함수를 유지할 수 있다.
use
로 시작하는 내장된 함수
Component
의 최상단이나use
로 시작하는 함수의 최상단에서만 사용이 가능하다.- 내장된 함수 외에도 사용자가 커스텀할 수도 있다.
Browser Painting
이후에 실행될 코드를 작성할 때 사용한다.
👉 try catch
문을 이용하여 use(Layout)Effect
보다 좋게 지연된 처리를 할 수 있다.
useEffect
Hook
의 실행 시점을 조정하고 싶을 때
종속성 배열
이 없는 경우
👉 항상DOM Commit
이후에 실행된다.종속성 배열
이 빈 배열인 경우
👉 최초DOM Commit
이후에 실행된다.종속성 배열
에 상태를 요소로 넣은 경우
👉 해당 상태가 변경되었을 경우의DOM Commit
이후에만 실행된다.useEffect
가 중첩되지 않도록CleanUp
에 신경써야 한다.
👉useEffect
의return
에CleanUp
Function
을 작성한다.
고유한 ID
를 만들어준다.
Animation
을 적용할 때 사용하는 것이 적합하다.
👉 대신 성능이 저하될 수 있다.
DOM Commit
이후에 실행되기 때문에useEffect
보다 먼저 실행된다.
👉 애니메이션에 적합한 이유이다.
useMemo
와 동일하게 Rendering
간에 값을 기억하기 위해 사용한다.
useCallback(함수, 종속성배열) // 종속성배열이 바뀔 때마다 함수의 값을 기억한다.
useCallback
은 함수 값만 기억하고,useMemo
는 함수를 포함한 모든 값을 기억한다.
일반적으로 상위 요소에서 하위 요소로 state
를 전달할 때 발생하는Props Drilling
Issue
를 방지하기 위해 사용한다.
👉 중첩된 요소를 모두 거치지 않고 바로 전달할 수 있도록 한다.
외부 contexts
폴더에 Context
를 정의하여 사용한다.
읽기 전용
const 생성된컨텍스트 = createContext(초깃값);
useContext(생성된컨텍스트);
기본값
에 상태를 전달하고 변수에 할당한다.useContext
로 접근할 수 있다.
읽기/쓰기
const 생성된컨텍스트 = createContext(); // 빈 Context 생성
const [state, setState] = useState(초깃값); // 상태 생성
<생성된컨텍스트.Provider
displayName="확장프로그램에서 보여질 이름"
value={state, setState}
>
/* 빈 Context에 생성한 상태를 공급하고, 내부 Component에서 해당 상태를 사용할 수 있다. */
<사용할Component />
</...>
- 빈
Context
를 생성한다.- 상태를 생성한다.
- 생성한
Context
내부에서 사용할 상태와 하위 요소를 정의한다.
React
Component
Rendering
에 영향을 주지 않으면서,
다음 Rendering
에도 값을 기억하기 위한 수단이다.
DOM
요소에 접근할 때에도 사용된다.
👉queryselector
등보다 신뢰할 수 있다.
useRefs(초깃값) // Refs (참조 객체) 생성 => { current: 초깃값 }
gsap
을 이용하여 animation
을 구현하려면,
useRef
Hook
을 사용하여 명령형으로 useLayoutEffect
나 handle function
에서 사용한다.
사용법
useRef
객체를 생성한다.const circleRef = useRef(null); // { current: null }
JSX
요소에Refs
객체를 전달한다<figure ref={circleRef} // 유일한 요소로 지정한다. />
useLayoutEffect
또는Handle Function
을 연결하여 사용한다.useLayoutEffect(() => { gsap.set(circleRef.current, ...); } const handleEnter = (circleRef.current) => { gsap.to(circleRef.current, ...); };
prop-types
를 이용하여 props
의 type
을 검사하거나 지정해준다.
import { 내장메소드들 } from 'prop-types';
Component.propTypes = {
부여된props1: 속성.isRequired // '속성' 타입이어야 하고 필수값이다.
부여된props2: arrayOf(속성) // '속성'으로 구성된 배열이어야 한다.
부여된props3: oneOf([속성1, 속성2]) // '속성1', '속성2' 중 하나여야 한다.
부여된props4: shape({
key1: 속성1,
key2: 속성2
}) // key1과 key2를 가지며, value의 속성은 각각 '속성1', '속성2'이다.
부여된props5: exact({
key1: 속성1,
key2: 속성2
}) // shape과 똑같지만, 다른 key는 추가할 수 없다.
}
.eslintrc.cjs
의ignorePatterns
에linting
하지 않을 것들을 정의할 수 있다.
Page
별 title
을 설정하거나, Open Graph
를 만들어준다.
👉 검색엔진 최적화에 도움이 된다.
<HelmetProvider>
<하위컴포넌트>
<Helmet>
<title>이 페이지의 타이틀을 여기에 적습니다.</title>
</Helmet>
</하위컴포넌트>
</HelmetProvider>
State
와 Action
(동작 함수)을 함께 관리한다.
Context
보다 코드가 적다.State
를 관리할 때Context
를 사용할 경우에는,
State
가 변경되면,Context.Provider
하위의 모든 요소가re-Rendering
되는데,
Zustand
를 사용하면, 불필요한re-Rendering
을 방지할 수 있다.
/* Store 만들고, Hook에 담기 */
const store이름 = (set) => ({ // Zustand에 set함수를 매개변수로 가지는 store를 생성한다.
상태: 초깃값,
액션: (매개변수) => // 상태를 변경할 함수를 액션이라고 한다.
set((state) => ({
상태를 변경할 코드
}))
})
/* store는 상태와 상태를 변경할 함수(액션)을 가지는 함수이다. */
export const 커스텀훅 = create(store이름); // store를 create하여 커스텀훅에 할당한다.
/* Hook을 불러와 상태 관리하기 */
const 변수 = 훅((state) => state.상태|액션);
/* State나 Action 중 사용할 것을 반환하는 콜백함수를 훅의 매개변수로 불러온다. */
/* 인수로 콜백함수를 전달해 성능 저하를 방지한다. */
/* ------------------------------------------------------------------ */
const { 상태, 액션, ... } = 커스텀훅((state) => {
const { 상태, ...rest액션 } = state;
return rest액션;
};
/* 하나씩 빼지 않고, 구조 분해 할당으로 한번에 불러올 수도 있다. */
persist
를 사용하면localstorage
에 저장하여 새로고침해도 유지된다.create(persist())
사용할
Component
에서커스텀훅(콜백함수)
으로State
를 관리한다.
한번 불러온 데이터를 캐싱하여 사용자의 경험을 높이기 위해 사용한다.
const 변수 = new QueryClient({}); // 객체 생성
/* 인수로 사용할 기능들을 넣어준다. */
<QueryClientProvider client={변수}> // Component를 감싼다.
<하위컴포넌트 />
<ReactQueryDevtools /> // 개발 툴 Component
</QueryClientProvider>
index.html
➡️ layout.js
index.html
은 Build
시 생성된다.)File Convention
을 지켜야 한다.Client
인지 Server
인지 구분하는 것이 핵심이다.Client
File
은 use client
를 선언해야 한다.