Udemy 강의 "React 완벽 가이드 with Redux, Next.js, TypeScript" 를 보고 정리하였습니다.
컴포넌트, JSX, 속성, 상태
기본개념
JSX
JavaScript Syntax eXtension
-> but 브라우저에 사용 불가능합니다.
그래서 브라우저에 도달하기 전에 개발 서버에서 변환됩니다.
리액트에서의 컴포넌트
컴포넌트 = 자바스크립트 함수
- 컴포넌트의 첫글자는 대문자, PascalCase(MyHeader)
커스텀 컴포넌트는 실제로 렌더링된 DOM에 나타나지 않습니다.
동적 값 출력
외부에 정의된 값들을 가져옵니다.
import { CORE_CONCEPTS } from "./data.js";
import componentsImg from "./assets/components.png";
import propsImg from "./assets/config.png";
import jsxImg from "./assets/jsx-ui.png";
import stateImg from "./assets/state-mgmt.png";
export const CORE_CONCEPTS = [
{
image: componentsImg,
title: "Components",
description:
"The core UI building block - compose the user interface by combining multiple components."
},
{
image: jsxImg,
title: "JSX",
description:
"Return (potentially dynamic) HTML(ish) code to define the actual markup that will be rendered."
},
{
image: propsImg,
title: "Props",
description:
"Make components configurable (and therefore reusable) by passing input data to them."
},
{
image: stateImg,
title: "State",
description:
"React-managed data which, when changed, causes the component to re-render & the UI to update."
}
];
해당 데이터들을 출력할 컴포넌트 작성합니다.
props 를 통해 사용가능합니다.
function CoreConcept({ image, title, description }) {
return (
<li>
<img src={image} alt={title} />
<h3>{title}</h3>
<p>{description}</p>
</li>
);
}
여기서는 자바스크립트의 구조분해를 사용합니다.
function App() {
return (
<div>
<Header />
<main>
<section id="core-concepts">
<h2>Time to get started!</h2>
<ul>
<CoreConcept
title={CORE_CONCEPTS[0].title} // props
description={CORE_CONCEPTS[0].description}
image={CORE_CONCEPTS[0].image}
/>
<CoreConcept {...CORE_CONCEPTS[1]} />
</ul>
</section>
</main>
</div>
);
}
스프레드 연산자를 통해 데이터를 가져올 수 있습니다.
<CoreConcept {...CORE_CONCEPTS[1]} />
프로젝트 구조활용
App.jsx
import { CORE_CONCEPTS } from "./data.js";
import Header from "./components/Header";
import CoreConcept from "./components/CoreConcept";
function App() {
return (
<div>
<Header />
<main>
<section id="core-concepts">
<h2>Time to get started!</h2>
<ul>
<CoreConcept
title={CORE_CONCEPTS[0].title} // props
description={CORE_CONCEPTS[0].description}
image={CORE_CONCEPTS[0].image}
/>
<CoreConcept {...CORE_CONCEPTS[1]} />
</ul>
</section>
</main>
</div>
);
}
export default App;
Header, CoreConcept 를 컴포넌트 단위로 나누어 사용합니다.
Header.jsx
import reactImg from "../assets/react-core-concepts.png";
const reactDescriptions = ["Fundamental", "Crucial", "Core"];
function genRandomInt(max) {
return Math.floor(Math.random() * (max + 1));
}
export default function Header() {
const description = reactDescriptions[genRandomInt(2)];
return (
<header>
<img src={reactImg} alt="Stylized atom" />
<h1>React Essentials</h1>
<p>
{description} Fundamental React concepts you will need for almost any
app you are going to build!
</p>
</header>
);
}
export default 선언을 하여 외부에서 사용할 수 있습니다.
CoreConcept.jsx
export default function CoreConcept(props) {
return (
<li>
<img src={props.image} alt=".." />
<h3>{props.title}</h3>
<p>{props.description}</p>
</li>
);
}
props
라벨 label 으로 사용
app.jsx
TabButton
이벤트
구조분해 할당 사용
조건부 렌더링
이러한 탭이 있을 때
탭을 누르기 전에는
탭을 눌러달라는 문구를 띄우고 싶을 때
{!useSelectedTopic && <p> 주제를 선택해주세요 </p>}
{useSelectedTopic && (
<div id="tab-content">
<h3>{EXAMPLES[useSelectedTopic].title}</h3>
<p>{EXAMPLES[useSelectedTopic].description}</p>
<pre>
<code>{EXAMPLES[useSelectedTopic].code}</code>
</pre>
</div>
)}
함수를 통한 방법
let tabContent = <p> 주제를 선택해주세요 </p>;
if (useSelectedTopic) {
tabContent = (
<div id="tab-content">
<h3>{EXAMPLES[useSelectedTopic].title}</h3>
<p>{EXAMPLES[useSelectedTopic].description}</p>
<pre>
<code>{EXAMPLES[useSelectedTopic].code}</code>
</pre>
</div>
);
}
..
{tabContent}
JSX가 더 깔끔해지고 관리하기 더욱 용이해진다.
CSS 동적 스타일링
<TabButton
isSelected={useSelectedTopic === "components"}
onSelect={() => handleSelect("components")}
>
components
</TabButton>
<TabButton
isSelected={useSelectedTopic === "jsx"}
onSelect={() => handleSelect("jsx")}
>
JSX
</TabButton>
<TabButton
isSelected={useSelectedTopic === "props"}
onSelect={() => handleSelect("props")}
>
props
</TabButton>
<TabButton
isSelected={useSelectedTopic === "state"}
onSelect={() => handleSelect("state")}
>
state
</TabButton>
버튼 클릭시 isSelected에 값을 담아서 보낸다.
export default function TabButton({ children, onSelect, isSelected }) {
return (
<li>
<button className={isSelected ? "active" : undefined} onClick={onSelect}>
{children}
</button>
</li>
);
}
isSelected 값이 있으면 active가 활성화 되어서 css 가 적용되게 함
내장 map 을 사용하여 목록 데이터를 동적으로 출력
{/* <CoreConcept
title={CORE_CONCEPTS[0].title} // props
description={CORE_CONCEPTS[0].description}
image={CORE_CONCEPTS[0].image}
/>
<CoreConcept {...CORE_CONCEPTS[1]} /> */}
{CORE_CONCEPTS.map((conceptItem) => (
<CoreConcept key={conceptItem.title} {...conceptItem} />
))}
'Front-end > React\RN' 카테고리의 다른 글
React 리액트 props 속성 전달과 구조분해할당 (0) | 2024.03.05 |
---|---|
글로벌 영역에서 색상관리 (0) | 2023.08.16 |
게임 화면 작업 - 노치 고려해 SafeAreaView 활용, 제목 컴포넌트 생성 (0) | 2023.08.15 |
리액트네이티브, 화면 전환 (0) | 2023.08.14 |
리액트네이티브, 입력 검증 (0) | 2023.08.08 |
댓글