클래스형 컴포넌트 (Class Component )
1. 내보내기
1-1. default 내보내기
컴포넌트들은 보통 default로 내보낸다.
📑 App.js
import { Component } from "react"; //리엑트에서 Component 가져온다.
class App extends Component{
render(){
return (
<main className="main-container">
<h1>예산 계산기</h1>
<div>
</div>
</main>
)
}
}
//내보내기 default - 메인으로 내보냄
export default App;
2-1. 클래스 바로 내보내기
여러개 내보낼 수 있다.
📑 App.js
import { Component } from "react"; //리엑트에서 Component 가져온다.
export class App extends Component{
render(){
return (
<main className="main-container">
<h1>예산 계산기</h1>
<div>
</div>
</main>
)
}
}
export class AppB extends Component{
render(){
return (
<div className="test-container">
test
</div>
)
}
}
받아오는 부분도 수정이 필요하다 { 이름 }
으로 변경해야한다.
📑 index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { App, AppB } from './App';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
2. 컴포넌트에 마크업에 style 적용하기
2-1. 인라인적용
<div style={{ width: '100%', background: 'white', padding: '1rem' }}>
import { Component } from "react"; //리엑트에서 Component 가져온다.
class App extends Component{
render(){
return (
<main className="main-container">
<h1>예산 계산기</h1>
<div style={{width: '100%', background:'white',padding:'1rem'}}>
{/* Expense Form */}
</div>
<div style={{ width: '100%', background: 'white', padding: '1rem' }}>
{/* Expense list */}
</div>
</main>
)
}
}
//내보내기 default - 메인으로 내보냄
export default App;
2-2. css파일에 적용
📑App.css
.main-container{margin:0 auto;max-width:1280px;width:90%}
📑App.js
import { Component } from "react"; //리엑트에서 Component 가져온다.
import "./App.css"; // css 파일 연결
class App extends Component{
...
}
...
3. 컴포넌트 가져오기
3-1.여러개의 컴포넌트 생성
- 컴포넌트 폴더를 만들어 내부에 필요한 컴포넌트들을 생성한다.
- 컴포넌트 내용 구성 쉽게 구성하는 방법
rce
3-2.컴포넌트 연결
- 컨포넌트를 가져온다.
import 컨포넌트명 from "./components/ExpenseForm";
컨포넌트명
은 항상 대문자로 시작해야한다.- 컨포넌트를 원하는 자리에
<컨포넌트명 />
넣어준다.
📑 App.js
import { Component } from "react"; //리엑트에서 Component 가져온다.
import "./App.css";
import ExpenseForm from "./components/ExpenseForm"; // 1. 컨포넌트 가져오기
class App extends Component{
render(){
return (
<main className="main-container">
<h1>예산 계산기</h1>
<div style={{width: '100%', background:'white',padding:'1rem'}}>
{/* Expense Form */}
<ExpenseForm /> // 2. 컨포넌트 넣기
</div>
...
</main>
)
}
}
//내보내기 default - 메인으로 내보냄
export default App;
4. 리액트 아이콘 사용하기
리액트에서 아이콘을 사용하는 방법은 여러가지이지만 주로 rect-icons 모듈을 이용하여 아이콘을 구현한다.
4-1. 모듈설치
npm install react-icons
4-2. react-icons 사용방법
- 사용할 js 파일에서 연결
import { MdSend } from 'react-icons/md'
- 원하는 곳에
<MdSend>
추가
더 자세한 사항과 아이콘 정보는 아래 사이트에서 확인할 수 있다.
https://react-icons.github.io/react-icons/
React Icons
React Icons Include popular icons in your React projects easily with react-icons, which utilizes ES6 imports that allows you to include only the icons that your project is using. Installation (for standard modern project) npm install react-icons --save Usa
react-icons.github.io
5. Props를 통해 컴포넌트 간 데이터 전달
- Props 란 Properties의 줄임말이다.
- Props 는 상속하는 부모 컴포넌트로부터 자녀 컴포넌트에 데이터 등을 전달하는 방법
- Props 는 읽기 전용으로 자녀 컴포넌트 입장에서는 변하지 않는다. (변하려면 부모 컴포넌트에서 상태를 변경 시켜주어야한다.)
부모 컴포넌트 => 자녀 컴포넌트
5-1. 부모컴포넌트 데이터 전달방법
- 데이터 생성 :
initialExpenses =[...]
- 데이터 전달 :
<전달할컴포넌트 initialExpenses={this.initialExpenses}/>
📑App.js
iimport { Component } from "react"; //리엑트에서 Component 가져온다.
import "./App.css";
import ExpenseForm from "./components/ExpenseForm";
import Expenselist from "./components/Expenselist";
class App extends Component{
initialExpenses =[
{ id: 1, charge: "렌트비", amount: 16000 },
{ id: 2, charge: "교통비", amount: 20000 },
{ id: 3, charge: "숙박비", amount: 200000 },
{ id: 4, charge: "식비", amount: 56000 }
]
render(){
return (
<main className="main-container">
<h1>예산 계산기</h1>
<div style={{width: '100%', background:'white',padding:'1rem'}}>
...
</div>
<div style={{ width: '100%', background: 'white', padding: '1rem' }}>
{/* Expense list */}
<Expenselist initialExpenses={this.initialExpenses}/>
</div>
...
</main>
)
}
}
//내보내기 default - 메인으로 내보냄
export default App;
</div>
5-2. 자녀 데이터 받는 방법
- 데이터 가져오기:
this.props.initialExpenses
📑Expenselist.js
render() {
console.log(this.props.initialExpenses);
return (
<>
<ul className='list'>
<ExpenseItem />
</ul>
<button className='btn'>
목록지우기
<MdDelete className='btn-icon'></MdDelete>
</button>
</>
)
}
5-3.Map 메서드를 사용한 데이터 반환
배열내의 모든 요소 각각에 대하여 주어진 함수 호출 결과를 새로운 배열로 반환하는 것
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/map
Array.prototype.map() - JavaScript | MDN
map() 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환합니다.
developer.mozilla.org
- 데이터 전달 :
map
을 사용해 각각의 아이템을ExpenseItem
에 'expense={expense}'전달 해주고 있다. - 키속성 명시 : 해당 아이템의 유니크 값을 넣어주어야한다.
key={expense.id}
JSX key 속성이란?
리액트에서 요소의 리스트 나열시 key를 넣어줘야한다.
키는 리액트가 변경,추가 또는 제거된 항목을 식별하는데 도움이 된다. (가상돔 -> 변경 내역 -> 실제 돔 적용)
요소의 안정적인 ID를 부여하려면 배열 내부의 요소에 키를 제공해야한다.
이때 키로는 index는 비 추천되는 방법이다. 이유는 리스트가 추가되거나 제거 되면 리스트들의 key값도 변경되게 된다.
📑Expenselist.js
import React, { Component } from 'react'
import './ExpenseList.css'
import ExpenseItem from './ExpenseItem'
import { MdDelete } from 'react-icons/md'
export class Expenselist extends Component {
render() {
console.log(this.props.initialExpenses);
return (
<>
<ul className='list'>
{this.props.initialExpenses.map(expense=>{
return (
<ExpenseItem expense={expense} key={expense.id}/>
)
})}
</ul>
<button className='btn'>
목록지우기
<MdDelete className='btn-icon'></MdDelete>
</button>
</>
)
}
}
export default Expenselist
5-4. 각 아이템 받아오기
- 각 속성을 사용하여 아이템 요소 가져오기 :
{this.props.전달데이터명.키이름}
📑ExpenseItem.js
import React, { Component } from 'react'
import './ExpenseItem.css'
import { MdEdit, MdDelete } from 'react-icons/md'
export class ExpenseItem extends Component {
render() {
return (
<>
<li className='item'>
<div className='info'>
<span className='expense'>{this.props.expense.charge}</span>
<span className='amount'>{this.props.expense.amount}원</span>
</div>
<div>
<button className='edit-btn'><MdEdit /></button>
<button className='clear-btn'><MdDelete /> </button>
</div>
</li>
</>
)
}
}
export default ExpenseItem
6. Filter 메소드를 사용한 리스트 삭제 기능
Filter 메서드
주어진 함수의 테스트를 통과하는 모든요소를 모아 새로운 배열로 반환
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
Array.prototype.filter() - JavaScript | MDN
filter() 메서드는 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환합니다.
developer.mozilla.org
6-1. 부모컴포넌트 함수 전달
- 이벤트 함수 생성 :
handleDelete=(매개변수)=>{처리과정}
- 자식컴포넌트 전달 :
Expenselist
컴포넌트에handleDelete={this.handleDelete}
함수 전달 filter
메서드 사용 : 기존 리스트 배열initialExpenses
에 연결하여 각 요소와 전달받은id
값을 비교 일치 하지 않는 것만 새로운 배열로 만들어준다.
📑App.js
// 클릭 이벤트 함수 생성
// 아이템 제거
handleDelete = (id) => {
const newExpenses = this.initialExpenses.filter(expect=> expect.id !== id);
console.log(newExpenses)
}
render(){
return (
<main className="main-container">
<h1>예산 계산기</h1>
...
<div style={{ width: '100%', background: 'white', padding: '1rem' }}>
{/* Expense list */}
<Expenselist initialExpenses={this.initialExpenses} handleDelete={this.handleDelete} />
</div>
...
</main>
)
}
6-2. 자식컴포넌트 이벤트 재 전달
- 컴포넌트로 데이터 재 전달 : 실제 요소가 있는
ExpenseItem
컴포넌트에전달받은명칭={this.props.전달받은명칭}
으로 재 전달한다.
📑Expenselist.js
...
export class Expenselist extends Component {
render() {
console.log(this.props.initialExpenses);
return (
<>
<ul className='list'>
{this.props.initialExpenses.map(expense=>{
return (
<ExpenseItem
expense={expense}
key={expense.id}
handleDelete={this.props.handleDelete} // 전달
/>
)
})}
</ul>
...
</>
)
}
}
export default Expenselist
6-3. 실제 사용되는 컴포넌트에서 처리
- 버튼클릭 이벤트 추가 : 버튼 태그에
onClick
이벤트를 추가해준다. - 부모컴포넌트에서 전달 받은 함수 사용 :
this.props.handleDelete(this.props.expense.id)
전달받은 함수를 가져와 사용한다.
📑ExpenseItem.js
...
export class ExpenseItem extends Component {
render() {
return (
<>
<li className='item'>
...
<div>
<button className='edit-btn'
onClick={()=>
this.props.handleDelete(this.props.expense.id)
}
><MdEdit />
</button>
...
</div>
</li>
</>
)
}
}
⭐ 7. React State 화면변화 리랜더링!
리액트에서 데이터가 변할 때 화면을 다시 렌더링 해주기 위해서는 React State 를 사용해야한다.
React State란
컴포넌트의 렌더링 결과물에 영향을 주는 데이터를 갖고 있는 객체로 컴포넌트 안에서 관리된다.
State 가 변경되면 컴포넌트는 리랜더링 된다.
기억해야하는 데이터를 State를 이용하여 기억시켜야한다.
7-1. State를 사용하여 데이터 기억
App.js
파일에서 기존에는 데이터를 배열로 생성만 해주었는데, State를 생성해서 내부에 기억 시켜주는 로직으로 변경 해주었다.
- State 생성 : 클래스 내부에 추가해준다.
constructor(props){ ... this.state={ 데이터이름 :[{데이터},{},{}]}
= > ※ 하위설명 참고 - State 데이터 사용 : State 내부에 생성한 데이터는
this.state.데이터이름
으로 사용될 수 있다. - State 데이터 상태 변경시 적용 :
this.setState({ 데이터이름 : 변경된데이터 })
이와 같이 변화 시켜 줄 수 있다.
📑App.js
class App extends Component{
//1. State 생성
constructor(props){
super(props);
this.state ={
expenses: [ // 이름
{ id: 1, charge: "렌트비", amount: 16000 },
{ id: 2, charge: "교통비", amount: 20000 },
{ id: 3, charge: "숙박비", amount: 200000 },
{ id: 4, charge: "식비", amount: 56000 }
]
}
}
// 클릭 이벤트 함수 생성
handleDelete = (id) => {
const newExpenses = this.state.expenses.filter(expect=> expect.id !== id); //2-1. State 사용
this.setState({ expenses : newExpenses }) //3. State 변화 적용
}
render(){
return (
<main className="main-container">
...
<div style={{ width: '100%', background: 'white', padding: '1rem' }}>
{/* Expense list */}
<Expenselist initialExpenses={this.state.expenses} handleDelete={this.handleDelete} />//2-2. State 사용
</div>
...
</main>
)
}
...
※ State 생성 더 깊게 알아보기 ==> 자바와 동일한 문법
1. Constructor `constructor` 생성자를 사용하면 인스턴스화 된 객체에서 다른 메서드를 호출하기 전에 수행해야 하는 사용자 지정 초기화를 제공할 수 있다.
- 초기에 생성되어야 하는 것들을 지정.
- 이렇게 생성된 변수는 this.명칭 으로 바로 사용가능하다.
2. super : 부모클래스 호출 => 부모클래스 생성
리액트에서 super로 props
를 인자로 전달하는 이유는 React.Component 객체가 생성될때 props
속성을 초기화 하기 위해 전달한다.
constructor(props){
super(props);
this.state ={
expenses: [ // 이름
{ id: 1, charge: "렌트비", amount: 16000 },
{ id: 2, charge: "교통비", amount: 20000 },
{ id: 3, charge: "숙박비", amount: 200000 },
{ id: 4, charge: "식비", amount: 56000 }
]
}
}
'FrontEnd > React' 카테고리의 다른 글
[ React ] axios 사용과 영화 데이터 가져오기 (0) | 2023.08.30 |
---|---|
[ React ] 함수형 컴포넌트 (Functional Component) - ReactHooks(State) (0) | 2023.08.19 |
[ React ] JSX (Javascript syntax extension) (0) | 2023.08.17 |
[ React ] Single Page Application (SPA) (0) | 2023.08.17 |
[ React ] 리액트 설치 'Create React App' (0) | 2023.08.17 |