공식 문서
https://ko.legacy.reactjs.org/docs/components-and-props.html
리액트(React)에서 컴포넌트는 UI를 구성하는 독립적인 요소이다.
각 컴포넌트는 자체적으로 상태(state)를 가지고 있고,
이를 통해 데이터를 관리하고 렌더링을 한다.
컴포넌트는 데이터(props)를 입력받아 View(state) 상태에 따라 DOM Node를 출력하는 함수이다.
컴포넌트는 재사용 가능하며, 여러 컴포넌트를 조합하여 복잡한 UI를 구성할 수 있다.
예를 들어, 웹 애플리케이션에서 블로그 포스트를 표시하는 페이지를 만든다고 가정해보면 이 페이지는 여러 요소로 구성될 수 있다. 예를 들어, 블로그 포스트 제목, 내용, 작성자, 작성일 등이 있을 수 있는데 이러한 각 요소를 독립된 컴포넌트로 만들 수 있습니다.
예를 들어, Post라는 컴포넌트는 블로그 포스트를 나타냅니다. 이 Post 컴포넌트는 제목, 내용, 작성자 등을 표시하는 서브 컴포넌트를 포함할 수 있습니다. 또한, 이러한 Post 컴포넌트는 블로그 페이지에서 여러 번 재사용될 수 있습니다.
vscode에서는 "React Functional Component"를 사용할 때 사용되는 축약어로
rfce 를 입력하고 엔터를 누르면 React 함수형 컴포넌트의 기본 구조가 자동으로 생성된다.
import React from 'react'
function ComponentName() {
return (
<div>
</div>
)
}
export default ComponentName;
- import 문 : 컴포넌트에서 리액트를 import 한다.
이를 통해 리액트 라이브러리에서 제공하는 기능들을 사용할 수 있다.
- 함수형 컴포넌트 선언 : function 키워드를 사용하여 컴포넌트를 선언한다.
이때 컴포넌트 이름을 지정하고, 괄호 안에는 컴포넌트에 전달될 props를 받을 수 있다.
- JSX 반환 : 함수의 본문에서는 JSX를 사용하여 컴포넌트의 UI를 정의한다.
JSX는 JavaScript를 확장한 문법으로, HTML과 비슷한 형태로 UI를 작성할 수 있다.
기본 폼에서는<div>
요소를 반환하고 있고 이 안에는 컴포넌트의 내용이 들어간다.
- export 문 : 컴포넌트를 내보낸다는 뜻
이를 통해 다른 파일에서 해당 컴포넌트를 import하여 사용할 수 있다.
컴포넌트 간에 데이터를 전달하는 방법과 이를 통해 UI를 구성하는 방법에 대한 간단한 예시
부모 컴포넌트(ParentComponent):
이 컴포넌트는 자식 컴포넌트인 ChildComponent를 렌더링 / 부모 컴포넌트는 자식 컴포넌트에게 name과 age라는 props를 전달
자식 컴포넌트(ChildComponent): name과 age를 받아 화면에 출력
🎅 부모 컴포넌트
import React from 'react';
import ChildComponent from './ChildComponent'; // ChildComponent를 import
function ParentComponent() {
return <ChildComponent name="gamza" age={10} />;
}
export default ParentComponent; // ParentComponent를 default로 export
👻 자식 컴포넌트
import React from 'react';
function ChildComponent(props) {
return (
<div>
<p>Name: {props.name}</p>
<p>Age: {props.age}</p>
</div>
);
}
export default ChildComponent; // ChildComponent를 default로 export
++ index.js에서는 애플리케이션의 루트 컴포넌트를 렌더링한다.
이 예제의 경우 확인을 위해 부모 컴포넌트가 루트 컴포넌트라 가정하고
렌더링을 할 수 있게 설정함
import React from 'react';
import ReactDOM from 'react-dom';
import ParentComponent from './ParentComponent'; // 부모 컴포넌트를 import
ReactDOM.render(
<React.StrictMode>
<ParentComponent /> {/* 부모 컴포넌트 렌더링 */}
</React.StrictMode>,
document.getElementById('root')
);
ReactDOM.render() 함수를 사용하여 부모 컴포넌트를 렌더링한다.
이때 부모 컴포넌트는 src 디렉토리에 있는 파일에서 import한 것이다.
index.js 파일 : 리액트 애플리케이션의 진입점(entry point)
주로 ReactDOM을 사용하여 애플리케이션을 렌더링(render)하고, 필요한 경우 전역 설정을 수행한다. 주로 사용되는 설정은 라우팅 설정이나 상태 관리 라이브러리 등이 있다.
출처 https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/
컴포넌트가 실행될 때 작동 순서
constructor -> render -> componentDidMount -> (fetch 완료) -> render -> (setState) -> componentDidUpdate -> render -> componentWillUnmount
흐름 (세부적으론 더 많은 함수들이 있는 것 같은데 차차 만나게 될 듯 !!)
앱이 실행되자마자 해줘야 하는 작업들을 constructor에 넣자
( 이 안에 state를 만든다 )
render 함수내에서는 ui를 그려준다.
componentDidMount는 ui 세팅이 완료되면(render 후) 호출될 함수
( ex) api call )
state가 업데이트 되거나, props가 업데이트 되거나,
업데이트가 강요되는 사항 등이 있을 때 다시 render 발생
componentDidUpdate 함수 호출
(리렌더링을 마친 후 화면에 원하는 변화가 모두 반영되고 난 뒤(state가 전부 업데이트 된 후) 호출되는 메서드이다.)
테스트 - > 버튼을 누르면 수가 1씩 증가하는 컴포넌트를 작성하고 실행하면
버튼을 눌렀을 때 카운터2라는 요소는 화면에는 1로 표시되지만 콘솔에선 여전히 0인
이유가 비동기적으로 처리되기 때문이다.
그래서 실제로는 아직 값이 바뀐 상태가 아닌 (한 단계 전인 상태) 것이다 !
이런 부분에서 최신 업데이트된 state 값을 받아볼 수 있는 게 componentDidUpdate 함수의 역할이다.
(state가 업데이트 된 이후 해야 할 작업을 componentDidupdate 안에서 작성하자)
테스트로 1 ~ 3 부분을 로그 작성후 앱을 실행해보면 어떤 순서로 작성해도
constructor - > render - > componentDidMount 순으로 찍히는 걸 확인할 수 있다.
근데 궁금한 건 왜 자꾸 ... 두번씩 호출히지 ???
해결한 부분 - > StrictMode Wrapper를 없애니 해결됐다 👀
함수 컴포넌트에서는 리액트 hook중 하나인 useEffect 함수가
클래스컴포넌트 사이클의 componentDidMount 역할을 한다!
React의 함수형 컴포넌트에서 생명주기 메서드를 대체하는 데 사용되는 거니까
useEffect를 사용하면 컴포넌트가 렌더링될 때마다 특정 동작을 수행하도록 지정할 수 있다.
useEffect()는 컴포넌트가 마운트되거나 업데이트될 때마다 실행되며, 필요에 따라 정리(clean-up) 작업을 수행할 수 있다.
useEffect( ) 기본 형식
import React, { useEffect } from 'react';
function MyComponent() {
useEffect(() => {
// 수행할 동작 작성
// 컴포넌트가 마운트되거나 업데이트될 때마다 실행됨
// 이펙트가 반환하는 함수는 정리(clean-up) 함수로, 컴포넌트가 언마운트될 때 실행됨
return () => {
// 정리 작업 수행
};
});
return (
// 컴포넌트의 JSX를 반환
);
}
useEffect는 앱 실행 후 첫번째 렌더 후에 한 번 실행이 됨
(이 때 화면에 처음 보여줘야 할 데이터들에 대한 api 호출 수행하는 등의 작업을 할 수 있음 )
useEffect()는 두 개의 인자를 받는데 첫 번째 인자는 특정 동작을 정의하는 함수이다. 이 함수는 컴포넌트가 마운트되거나 업데이트될 때 실행된다.
두 번째 인자는 의존성 배열(dependency array)로, 이 배열에 포함된 값이 변경될 때마다 특정 동작을 다시 실행하도록 설정할 수 있음
일반적으로 의존성 배열을 빈 배열([])로 설정하면 컴포넌트가 마운트될 때만 useEffect()의 콜백 함수가 실행되며, 컴포넌트가 언마운트될 때만 정리(clean-up) 함수가 실행된다.
배열에 들어가는 state 값중에 하나라도 변하면 useEffect가 호출됨 !
(여러 state값이 동시에 업데이트 되어도 한 번만 호출됨)
useEffect()는 주로 데이터 가져오기, 구독 설정, 이벤트 리스너 등과 같은 side effect를 처리하는 데 사용되고
이는 클래스형 컴포넌트의 componentDidMount, componentDidUpdate, componentWillUnmount 등의 생명주기 메서드와 유사한 역할을 수행하게 된다.
흐름
컴포넌트 내부 Mounting
컴포넌트가 호출되었을 때, 가장 먼저 컴포넌트 내부에서 Mounting을 한다.
(라이프사이클 메소드 x)
컴포넌트 return 실행
컴포넌트에서 return이 실행된다.
(라이프사이클 메소드는 x)
useEffect Mounting
렌더링 이후 실행
useEffect Updating
컴포넌트 내부의 값이 업데이트될 때 실행
useEffect Unmounting
컴포넌트가 페이지에서 사라질 때 실행
리액트 State / lifecycle
https://ko.legacy.reactjs.org/docs/state-and-lifecycle.html
https://react.vlpt.us/basic/25-lifecycle.html
https://velog.io/@jeanbaek/React-Lifecycle