단순한 js함수 but jsx 반환 -> 컴포넌트
isLogginedIn 상태에 따른 메시지 렌더링
함수형
상태, 생명주기(Hooks) 메서드 가능
단순 간결
클래스형보다 가볍고 성능이 약간 나을수도
클라스형과 차이 : 작성 방식과 상태 관리 방식에 차이
but 동일하게 리액트에 의해 처리 돼 돔으로 랜더링
jsx
js코드 안에 html과 유사한 구문 사용할 수 있게 해줌
실제로 js로 변환, React.createElement()호출로 변환
var, cond, undefined, style, classname, comment
- var : const 변수 사용
const name = "React";
<h1>Hello, {name}!</h1>
변수 사용하고, jsx 안에서 {name}으로 변수 참조
- condition rendering : 조건 변수와 삼항 연산자 사용한 조건부 렌더링
const isLoggedIn = true;
{isLoggedIn ? ( A ! ) : ( B !)}
- undefined 값 처리 ( ‘기본값 ||’ 연산자로 처리 )
const name = undefined
{name || “Guest”}
- Style 적용 : divStyle 객체 정의 => style 속성에 객체 전달해 속성 적용
const divStyle = { color : ‘blue’}
<div style = {divStyle} >
- className : html class 속성이 리액트 내에서는 className으로 사용됨
import React from ‘react’
import ‘./App.css’ //css파일 import
<div className =“my-class”>
- Comment 주석 : jsx내부에서는 {/* 내부주석 */}f형태로. { /* jsx주석 != js 주석 }
<div> { /* 내부 주석*/ } { // js 내부 주석 }
- props(속성) : 컴포넌트간 데이터 전달 방법
부모컴포 To 자식컴포 데이터 전달하는 매개체, 각 컴포넌트 연결하고 상호작용 가능케 하는 연결부
- 부모는 레고 세트를 만들고, 개별 블록(자식 컴포넌트) 배치
App 컴포넌트는 Greeting 컴포넌트 두 번 사용함 .
각각 Greeting 컴포넌트에 다른 props 전달
- 자식은 레고 블럭. ‘name’이라는 연결부(‘props’)를 통해 다양한 데이터 받음
각각의 Greeting 컴포넌트는 부모 컴포넌트에서 전달된 ‘name’을 사용해 다른 결과 렌더링함
- probs에 기본값 설정 가능
Greeting.defaultProps = { name = ‘Guest’ }
- props.children : 컴포넌트가 포함하는 자식 요소 (부모가 자식 포함) return {props.children}
- 상위 to 하위 (비구조화 할당) : 부모에서 자식으로 props 전달할 때, 비구조화 할당 사용 가능
비구조화 할당은 큰 상자에서 각각의 항목을 꺼내어 정리하는 것과 비슷함
- props의 자료형을 확인하고, 맞지 않을 경우 콘솔에 경고 출력
AgeComponent.propTypes = {
age: PropTypes.number.isRequired
};
- props required ; 특정 props 반드시 필요함 명시해서 전달되지 않으면 경고 출력
Greeting.propType = { name: PropTypes.string.isRequired }
- props class
- compose component (header - body - footer 컴포넌트)
- extract component (컴포넌트에서 일부 코드 별도 컴포넌트로 분리)
부모-자식 : props로 데이터 전달
=> 데이터의 전달과 구조화
추출 : 일부 코드 별도 컴포넌트로 분리해 재사용성과 가독성 업
=> 재사용성과 가독성 증진
- 객체로 js와 css 표기법 : js에서는 카멜케이스, css에서는 케밥 케이스
const style = { borderRadius : , backgroundColor : }
- import & export : 어떤 컴포넌트 내보내고 가져와서 new 컴포넌트 만들거나 만든 컴포넌트로 다른 컴포넌트 만들기 등
렌더링 : “어떤 형태의 데이터를 시각적 결과물로 변환하는 과정”
- 웹 : html 생성하고 브라우저에 표시하는 과정
- 리액트 : Virtual DOM 사용해 min DOM 변경만 실제 DOM에 반영
초기 렌더링 : 컴포넌트 마운트 될 때 jsx to 가상 DOM 변환 & 이를 실제 DOM에 반영 과정
리렌더링 : 상태(state)나 속성(props) 변경될 때, 변경 내용 반영하여 가상 DOM과 실제 DOM을 리업데이트 과정
컴넌 만들고, css먹이고, 렌더링되어(, index.html의 id=root 부분에 ㄱㄱ
props는
부모 to 자식 데이터 전달
readonly(자식에서 수정 불가)
전달된 데이터로 렌더링을 다르게 수행 ㄱㄴ
부모 컴포넌트에서 자식 컴포넌트로 `props`를 전달하는 것은 리액트의 기본 개념 중 하나입니다. 이를 통해 부모 컴포넌트는 자식 컴포넌트에 데이터를 전달하고, 자식 컴포넌트는 이 데이터를 사용하여 UI를 렌더링합니다. 또한, 자식 컴포넌트에 콜백 함수를 전달하여 자식 컴포넌트가 부모 컴포넌트의 상태를 업데이트할 수 있도록 할 수도 있습니다.
### 예제
#### 부모 컴포넌트에서 자식 컴포넌트로 `props`를 전달하는 기본 예시
##### 부모 컴포넌트
```jsx
import React, { useState } from 'react';
import ChildComponent from './ChildComponent';
function ParentComponent() {
const [message, setMessage] = useState('Hello from Parent');
const updateMessage = (newMessage) => {
setMessage(newMessage);
};
return (
<div>
<h1>Parent Component</h1>
<p>Message: {message}</p>
<ChildComponent message={message} onMessageChange={updateMessage} />
</div>
);
}
export default ParentComponent;
```
##### 자식 컴포넌트
```jsx
import React, { useState } from 'react';
function ChildComponent({ message, onMessageChange }) {
const [inputValue, setInputValue] = useState('');
const handleChange = (e) => {
setInputValue(e.target.value);
};
const handleClick = () => {
onMessageChange(inputValue);
};
return (
<div>
<h2>Child Component</h2>
<p>Received Message: {message}</p>
<input type="text" value={inputValue} onChange={handleChange} />
<button onClick={handleClick}>Update Message</button>
</div>
);
}
export default ChildComponent;
```
### 설명
1. **부모 컴포넌트 (`ParentComponent`)**:
- `message`라는 상태를 관리합니다.
- `updateMessage` 함수는 새로운 메시지를 설정하는 함수입니다.
- `ChildComponent`에 `message`와 `onMessageChange` 콜백 함수를 `props`로 전달합니다.
2. **자식 컴포넌트 (`ChildComponent`)**:
- `props`로 받은 `message`를 표시합니다.
- 입력 필드의 값을 상태로 관리하고, 버튼 클릭 시 부모의 `onMessageChange` 콜백 함수를 호출하여 새로운 메시지를 전달합니다.
### 데이터 흐름
1. **부모에서 자식으로 데이터 전달**:
- 부모 컴포넌트는 자식 컴포넌트에 `message`와 `onMessageChange` 콜백 함수를 `props`로 전달합니다.
- 자식 컴포넌트는 `props`로 받은 `message`를 UI에 표시합니다.
2. **자식에서 부모로 이벤트 전달**:
- 자식 컴포넌트는 입력 필드의 값을 상태로 관리하고, 사용자가 입력한 값을 `onMessageChange` 콜백 함수를 통해 부모 컴포넌트에 전달합니다.
- 부모 컴포넌트는 `onMessageChange` 콜백 함수에서 전달받은 값을 사용하여 `message` 상태를 업데이트합니다.
이 예제는 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달하고, 자식 컴포넌트가 부모 컴포넌트의 상태를 업데이트하는 방법을 보여줍니다. 이를 통해 리액트의 단방향 데이터 흐름을 이해할 수 있습니다.
리액트를 처음 배울 때 알아두면 좋을 중요한 개념들을 설명하고 요약해드리겠습니다. 이 개념들은 리액트를 효율적으로 사용하고 이해하는 데 도움이 될 것입니다.
### 1. React 기본 개념
#### 컴포넌트
리액트 애플리케이션은 컴포넌트라는 독립적인, 재사용 가능한 코드 조각으로 구성됩니다. 컴포넌트는 함수형 또는 클래스형으로 작성할 수 있습니다.
#### JSX (JavaScript XML)
JSX는 JavaScript 코드 안에 HTML과 유사한 구문을 사용할 수 있게 해줍니다. 브라우저가 이해할 수 있도록 Babel 같은 도구가 JSX를 JavaScript로 변환합니다.
```jsx
const element = <h1>Hello, world!</h1>;
```
### 2. 상태와 생명주기
#### 상태 (State)
상태는 컴포넌트의 동적 데이터를 관리하는 객체입니다. 상태는 `useState` 훅을 사용해 함수형 컴포넌트에서 선언하고 관리할 수 있습니다.
```jsx
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
}
```
#### 생명주기 (Lifecycle)
컴포넌트는 생성, 업데이트, 소멸의 생명주기 단계가 있습니다. 클래스형 컴포넌트에서는 생명주기 메서드를 사용하며, 함수형 컴포넌트에서는 `useEffect` 훅을 사용해 생명주기 이벤트를 처리합니다.
```jsx
import React, { useEffect } from 'react';
function Timer() {
useEffect(() => {
const timer = setInterval(() => {
console.log('Tick');
}, 1000);
return () => clearInterval(timer); // Cleanup on unmount
}, []);
return <div>Timer</div>;
}
```
### 3. Props
#### Props (속성)
Props는 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달하는 방법입니다. Props는 읽기 전용이며 자식 컴포넌트에서 수정할 수 없습니다.
```jsx
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
function App() {
return <Welcome name="Sara" />;
}
```
#### 기본 Props 설정
기본값을 설정하여 컴포넌트에 props가 전달되지 않았을 때 사용할 값을 지정할 수 있습니다.
```jsx
function Greeting({ name }) {
return <h1>Hello, {name}</h1>;
}
Greeting.defaultProps = {
name: 'Guest',
};
```
### 4. 이벤트 핸들링
리액트에서 이벤트는 CamelCase로 작성되며, 함수로 처리합니다.
```jsx
function Toggle() {
const [isToggleOn, setToggle] = useState(true);
function handleClick() {
setToggle(!isToggleOn);
}
return (
<button onClick={handleClick}>
{isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
```
### 5. 폼과 입력 처리
리액트에서 폼을 처리하는 것은 상태를 사용하여 입력값을 제어하는 것을 의미합니다.
```jsx
function NameForm() {
const [value, setValue] = useState('');
function handleChange(event) {
setValue(event.target.value);
}
function handleSubmit(event) {
alert('A name was submitted: ' + value);
event.preventDefault();
}
return (
<form onSubmit={handleSubmit}>
<label>
Name:
<input type="text" value={value} onChange={handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
```
### 6. 컨디셔널 렌더링
리액트에서는 특정 조건에 따라 다른 컴포넌트를 렌더링할 수 있습니다.
```jsx
function Greeting({ isLoggedIn }) {
if (isLoggedIn) {
return <h1>Welcome back!</h1>;
}
return <h1>Please sign up.</h1>;
}
```
### 7. 리스트와 키
리스트를 렌더링할 때는 각 항목에 고유한 키를 제공해야 합니다. 이는 리액트가 각 항목을 식별하고 효율적으로 업데이트하는 데 도움이 됩니다.
```jsx
function NumberList({ numbers }) {
const listItems = numbers.map((number) =>
<li key={number.toString()}>
{number}
</li>
);
return <ul>{listItems}</ul>;
}
```
### 8. 리액트 라우터
리액트 애플리케이션에서 페이지 간 네비게이션을 위해 리액트 라우터를 사용할 수 있습니다.
```jsx
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
function App() {
return (
<Router>
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/users">
<Users />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</Router>
);
}
```
### 9. Context API
Context API는 컴포넌트 트리 전체에 데이터를 전역적으로 제공할 수 있는 방법입니다.
```jsx
const ThemeContext = React.createContext('light');
function App() {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar() {
return (
<div>
<ThemedButton />
</div>
);
}
function ThemedButton() {
const theme = useContext(ThemeContext);
return <button theme={theme}>Themed Button</button>;
}
```
### 10. Error Boundary
에러 경계를 사용하여 컴포넌트에서 발생하는 오류를 잡고 UI를 보호할 수 있습니다.
```jsx
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
// 에러 로깅
}
render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
function App() {
return (
<ErrorBoundary>
<MyComponent />
</ErrorBoundary>
);
}
```
### 11. 성능 최적화
성능 최적화를 위해 리액트는 `React.memo`, `useMemo`, `useCallback` 등의 훅을 제공합니다.
```jsx
const MemoizedComponent = React.memo(function MyComponent(props) {
/* 렌더링 로직 */
});
function ParentComponent({ a, b }) {
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
const memoizedCallback = useCallback(() => {
doSomething(a, b);
}, [a, b]);
return (
<MemoizedComponent value={memoizedValue} onClick={memoizedCallback} />
);
}
```
### 12. 코드 스플리팅
코드 스플리팅을 통해 초기 로드 시간을 줄이고 필요할 때만 코드를 로드할 수 있습니다.
```jsx
import React, { Suspense, lazy } from 'react';
const OtherComponent = lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
</div>
);
}
```
이 요약과 설명이 리액트를 배우고 사용하는 데 큰 도움이 되길 바랍니다. 중요한 개념을 이해하고 연습하면 리액트로 효율적인 애플리케이션을 만들 수 있습니다.
'네이버 클라우드 캠프' 카테고리의 다른 글
JPA_엔티티 그래프 (0) | 2024.05.28 |
---|---|
JPA_값 타입 객체 (0) | 2024.05.28 |
React 입문 - Hook, props (0) | 2024.05.18 |
React 입문 - 기본 파일 구조 (0) | 2024.05.17 |
React 입문 - 부모 자식 비유 (0) | 2024.05.17 |