리액트 기본기능
첫 컴포넌트 만들기
- App.js 파일에 Header, Body, Footer 컴포넌트를 만들어보자.
import React from 'react'
const Header = () => {
return (
<div>
<h1>Header</h1>
</div>
)
}
const Body = () => {
return (
<div>
<h1>Body</h1>
</div>
)
}
const Footer = () => {
return (
<div>
<h1>Footer</h1>
</div>
)
}
function App() {
return (
<div>
<Header />
<Body />
<Footer />
</div>
)
}
export default App
컴포넌트 분리하기
- Header, Body, Footer 컴포넌트를 따로 파일로 분리해보자.
// Header.js
import React from 'react'
const Header = () => {
return (
<div>
<h1>Header</h1>
</div>
)
}
export default Header
// Body.js
import React from 'react'
const Body = () => {
return (
<div>
<h1>Body</h1>
</div>
)
}
export default Body
// Footer.js
import React from 'react'
const Footer = () => {
return (
<div>
<h1>Footer</h1>
</div>
)
}
export default Footer
// App.js
import React from 'react'
import Header from './Header'
import Body from './Body'
import Footer from './Footer'
function App() {
return (
<div>
<Header />
<Body />
<Footer />
</div>
)
}
export default App
JSX 란?
- jsx는 자바스크립트의 확장 문법으로, 자바스크립트 안에서 html을 사용할 수 있게 해준다.
import React from 'react'
function Body() {
// number라는 변수를 선언하고 10을 할당
const number = 10
const num1 = 1
const num2 = 2
const str1 = 'Hello'
const str2 = 'World'
const bool1 = true
const bool2 = false
return (
<div>
<h1>Body</h1>
{/* number 변수를 출력 */}
<p>{number}</p>
{/* num1과 num2를 더한 값을 출력 */}
<p>{num1 + num2}</p>
{/* str1과 str2를 합친 값을 출력 */}
<p>{str1 + str2}</p>
{/* bool1이 true이면 '참'을 출력, false이면 '거짓'을 출력 */}
<p>{bool1 ? '참' : '거짓'}</p>
{/* not 연산자를 사용하여 bool1이 true이면 '거짓'을 출력, false이면 '참'을 출력 */}
<p>{!bool1 ? '참' : '거짓'}</p>
{/* and 연산자를 사용하여 bool1과 bool2가 모두 true이면 '참'을 출력, 아니면 '거짓'을 출력 */}
<p>{bool1 && bool2 ? '참' : '거짓'}</p>
{/* or 연산자를 사용하여 bool1과 bool2 중 하나라도 true이면 '참'을 출력, 아니면 '거짓'을 출력 */}
<p>{bool1 || bool2 ? '참' : '거짓'}</p>
</div>
)
}
- JSX 문법에서 지켜야 할 것
- JSX 문법에서는 태그를 열었으면 닫아야 한다.
import React from 'react'
function Body() {
return (
<div>
<h1>Body</h1>
<p>태그를 열었으면 닫아야 합니다.</p>
</div>
)
}
- JSX 문법에서는 태그를 여러 개 사용할 때는 하나의 태그로 감싸야 한다.
import React from 'react'
function Body() {
return (
<>
<h1>Body</h1>
<p>태그를 여러 개 사용할 때는 하나의 태그로 감싸야 합니다.</p>
</>
)
}
객체 출력하기
- 객체를 출력할 때는 객체를 {}로 감싸고, 객체 내부의 값을 출력할 때는 .을 사용한다.
import React from 'react'
function Body() {
const obj = {
name: '홍길동',
age: 20,
}
return (
<div>
<h1>Body</h1>
{/* obj 객체의 name 속성을 출력 */}
<p>{obj.name}</p>
{/* obj 객체의 age 속성을 출력 */}
<p>{obj.age}</p>
</div>
)
}
배열 출력하기
- 배열을 출력할 때는 배열을 {}로 감싸고, 배열 내부의 값을 출력할 때는 []를 사용한다.
import React from 'react'
function Body() {
const arr = [1, 2, 3, 4, 5]
return (
<div>
<h1>Body</h1>
{/* arr 배열의 첫 번째 요소를 출력 */}
<p>{arr[0]}</p>
{/* arr 배열의 두 번째 요소를 출력 */}
<p>{arr[1]}</p>
{/* arr 배열의 세 번째 요소를 출력 */}
<p>{arr[2]}</p>
{/* arr 배열의 네 번째 요소를 출력 */}
<p>{arr[3]}</p>
{/* arr 배열의 다섯 번째 요소를 출력 */}
<p>{arr[4]}</p>
</div>
)
}
조건문 사용하기
삼항 연산자
- 삼항 연산자란 조건문을 사용할 때 사용하는 연산자로, 조건문이 참이면 A를 출력하고, 거짓이면 B를 출력한다.
import React from 'react'
function Body() {
const num = 10
return (
<div>
<h1>Body</h1>
{/* num을 2로 나눈 나머지가 0이면 '짝수'를 출력, 아니면 '홀수'를 출력 */}
<p>{num % 2 === 0 ? '짝수' : '홀수'}</p>
</div>
)
}
조건문을 이용한 조건부 렌더링
import React from 'react'
function Body() {
const num = 10
if (num % 2 === 0) {
return <h1>{num}은 짝수</h1>
} else {
return <h1>{num}은 홀수</h1>
}
}
and 연산자
- and 연산자란 두 개의 조건이 모두 참일 때 참을 출력하고, 아니면 거짓을 출력한다.
import React from 'react'
function Body() {
const num1 = 10
const num2 = 20
return (
<div>
<h1>Body</h1>
{/* num1이 10보다 크고, num2가 20보다 크면 '참'을 출력, 아니면 '거짓'을 출력 */}
<p>{num1 > 10 && num2 > 20 ? '참' : '거짓'}</p>
</div>
)
}
or 연산자
- or 연산자란 두 개의 조건 중 하나라도 참일 때 참을 출력하고, 아니면 거짓을 출력한다.
import React from 'react'
function Body() {
const num1 = 10
const num2 = 20
return (
<div>
<h1>Body</h1>
{/* num1이 10보다 크거나, num2가 20보다 크면 '참'을 출력, 아니면 '거짓'을 출력 */}
<p>{num1 > 10 || num2 > 20 ? '참' : '거짓'}</p>
</div>
)
}
반복문 사용하기
- 반복문을 사용할 때는 {}로 감싸고, 반복문 내부의 값을 출력할 때는 {}를 사용한다.
import React from 'react'
function Body() {
const arr = [1, 2, 3, 4, 5]
return (
<div>
<h1>Body</h1>
{/* arr 배열의 요소를 반복하여 출력 */}
{arr.map((item, index) => (
<p key={index}>{item}</p>
))}
</div>
)
}
이벤트 사용하기
- 이벤트를 사용할 때는 {}로 감싸고, 이벤트를 사용할 때는 {}를 사용한다.
import React from 'react'
function Body() {
const handleClick = () => {
alert('버튼이 클릭되었습니다.')
}
return (
<div>
<h1>Body</h1>
{/* 버튼을 클릭하면 handleClick 함수가 실행되도록 설정 */}
<button onClick={handleClick}>버튼</button>
</div>
)
}
상태 사용하기
- 상태를 사용할 때는 useState 함수를 사용한다.
import React, { useState } from 'react'
function Body() {
// count라는 상태를 만들고, 초기값을 0으로 설정
const [count, setCount] = useState(0)
return (
<div>
<h1>Body</h1>
{/* count 상태를 출력 */}
<p>{count}</p>
{/* 버튼을 클릭하면 count 상태를 1 증가시킴 */}
<button onClick={() => setCount(count + 1)}>증가</button>
</div>
)
}
상태 초기화하기
- 상태를 초기화할 때는 useState 함수에 초기값을 설정한다.
import React, { useState } from 'react'
function Body() {
// count라는 상태를 만들고, 초기값을 0으로 설정
const [count, setCount] = useState(0)
return (
<div>
<h1>Body</h1>
{/* count 상태를 출력 */}
<p>{count}</p>
{/* 버튼을 클릭하면 count 상태를 0으로 초기화 */}
<button onClick={() => setCount(0)}>초기화</button>
</div>
)
}
상태 변경하기
- 상태를 변경할 때는 useState 함수에 상태를 설정하고, 상태를 변경할 때는 set상태 함수를 사용한다.
import React, { useState } from 'react'
function Body() {
// count라는 상태를 만들고, 초기값을 0으로 설정
const [count, setCount] = useState(0)
return (
<div>
<h1>Body</h1>
{/* count 상태를 출력 */}
<p>{count}</p>
{/* 버튼을 클릭하면 count 상태를 1 증가시킴 */}
<button onClick={() => setCount(count + 1)}>증가</button>
</div>
)
}
컴포넌트에 값 전달하기
- 컴포넌트에 값을 전달할 때는 props를 사용한다.
- props로 하나의 값 전달하기
import React from 'react'
function Header(props) {
return (
<div>
<h1>{props.title}</h1>
</div>
)
}
// 구조 분해 할당을 사용하여 props를 사용
function Body(props) {
const { title } = props
return (
<div>
<h1>{title}</h1>
</div>
)
}
// 구조 분해 할당을 사용하여 props를 사용
function Footer({ title }) {
return (
<div>
<h1>{title}</h1>
</div>
)
}
function App() {
return (
<div>
<Header title="Header" />
<Body title="Body" />
<Footer title="Footer" />
</div>
)
}
export default App
- props로 여러 개의 값 전달하기
import React from 'react'
function Body(props) {
const { title, content } = props
return (
<div>
<h1>{title}</h1>
<p>{content}</p>
</div>
)
}
function App() {
return (
<div>
<Body title="Body" content="Body Content" />
</div>
)
}
- 스프레드 연산자를 사용하여 props 전달하기
import React from 'react'
function Body({ title, content }) {
return (
<div>
<h1>Body</h1>
<p>
{content} 고양이 {name}는 {favorite.join(', ')}를 좋아합니다. <br />
좋아하는 음식은 {favorite[0]}입니다. <br />
좋아하는 간식은 {favorite[1]}입니다. <br />
좋아하는 장난감은 {favorite[2]}입니다. <br />
{favorite.length > 3 ? '그 외의 것도 좋아합니다.' : ''}
</p>
</div>
)
}
// defaultProps를 사용하여 favorite가 없을 때 기본값을 설정
// favorite가 없을 때 기본값을 설정하지 않으면 에러가 발생
Body.defaultProps = {
favorite: [],
}
function App() {
const bodyProps = {
name: '김겨울',
content: '귀여운',
favorite: ['츄르', '습식사료', '반짝이 공'],
}
return (
<div>
<Body {...bodyProps} />
</div>
)
}
컴포넌트에서 이벤트 사용하기
이벤트란 사용자가 웹 페이지에서 발생하는 동작을 말한다.
이벤트를 사용할 때는 {}로 감싸고, 이벤트를 사용할 때는 {}를 사용한다.
- 이벤트 핸들링 : 사용자가 웹 페이지에서 발생하는 동작을 처리하는 것을 말한다.
- 이벤트 핸들러 : 이벤트가 발생했을 때 실행되는 함수를 말한다.
예) 햄스터가 도망가면 잡아야 한다. 이때, 햄스터가 도망가는 것이 이벤트이고, 햄스터를 잡는 것이 이벤트 핸들링이다. 햄스터를 잡는 것이 이벤트 핸들러이다.
- onClick 이벤트 사용하기
import React from 'react'
function EventClick() {
const handleClick = () => {
alert('버튼이 클릭되었습니다.')
}
return (
<div>
<h1>Body</h1>
{/* 버튼을 클릭하면 handleClick 함수가 실행되도록 설정 */}
<button onClick={handleClick}>버튼</button>
</div>
)
}
export default EventClick
- 이벤트 객체 사용하기
- 이벤트 객체란 이벤트가 발생했을 때 이벤트에 대한 정보를 가지고 있는 객체를 말한다.
import React from 'react'
function EventClick() {
// 이벤트 객체를 사용하여 이벤트 정보를 출력
// 이벤트 객체를 사용할 때는 함수의 매개변수로 e를 사용
// e 객체를 사용하여 이벤트 정보를 출력
// e.target은 이벤트가 발생한 요소를 가리킴
// target.name 속성을 사용하여 이벤트가 발생한 요소의 name 속성을 출력
const handleClick = (e) => {
console.log(e.target.name)
}
return (
<div>
<h1>Body</h1>
{/* 확인 버튼을 클릭하면 handleClick 함수가 실행돼 '확인'을 출력 */}
<button name="확인" onClick={handleClick}>
확인
</button>
{/* 취소 버튼을 클릭하면 handleClick 함수가 실행돼 '취소'를 출력 */}
<button name="취소" onClick={handleClick}>
취소
</button>
</div>
)
}
export default EventClick
컴포넌트에서 상태 사용하기
- State 상태란?
- State 상태란 컴포넌트 내부에서 사용하는 상태를 말한다.
- State 상태를 사용할 때는 useState 함수를 사용한다.
- State 기본 사용법
useState로 상태 만들기
const [light, setLight] = useState('off')
const [상태값, 상태를 변경하는 함수] = useState(초기값)
- useState 함수를 사용하여 상태를 만들 때는 상태의 이름을 설정하고, 상태의 값을 설정한다.
- useState 함수를 사용하여 상태를 만들면 배열이 반환되는데, 배열의 첫 번째 요소는 상태의 값이고, 두 번째 요소는 상태를 변경하는 함수이다.
import React, { useState } from 'react'
function Count() {
// count라는 상태를 만들고, 초기값을 0으로 설정
const [count, setCount] = useState(0)
return (
<div>
<h1>Body</h1>
{/* count 상태를 출력 */}
<p>{count}</p>
{/* 버튼을 클릭하면 count 상태를 1 증가시킴 */}
<button onClick={() => setCount(count + 1)}>증가</button>
</div>
)
}
export default Count
- '+' 버튼을 클릭하면 count 상태를 1 증가시킨다.
- set 함수를 호출해 State 값을 변경하면, 변경값을 페이지에 반영하기 위해 컴포넌트를 다시 렌더링한다.
- 이것을 '컴포넌트의 업데이트' 라고 한다.
- 컴포넌트가 페이지에 렌더링하는 값은 컴포넌트 함수의 반환값이다.
- 따라서 컴포넌트를 다시 렌더링한다고 함은 컴포넌트 함수를 다시 호출한다는 것을 의미한다.
컴포넌트 리렌더링
import React, { useState } from 'react'
function Count() {
// 호출할 때마다 콘솔에 '업데이트'가 출력되도록 설정
console.log('없데이트')
const [count, setCount] = useState(0)
return (
<div>
<h1>Body</h1>
{/* count 상태를 출력 */}
<p>{count}</p>
{/* 버튼을 클릭하면 count 상태를 1 증가시킴 */}
<button onClick={() => setCount(count + 1)}>증가</button>
</div>
)
}
export default Count
- 여러 개의 사용자 입력값을 상태로 관리하기
- 여러 개의 사용자 입력값을 상태로 관리할 때는 useState 함수를 여러 번 사용한다.
- 이름, 성별, 나이, 자기소개 입력받기
import React, { useState } from 'react'
function InputMultiple() {
const [name, setName] = useState('')
const [gender, setGender] = useState('')
const [age, setAge] = useState('')
const [intro, setIntro] = useState('')
// input 요소에 텍스트를 입력할 때마다 콘솔에 출력
const onChangeName = (e) => {
console.log('이름 변경된 값 : ', e.target.value)
setName(e.target.value)
}
// select 요소에 option을 선택할 때마다 콘솔에 출력
const onChangeGender = (e) => {
console.log('성별 변경된 값 : ', e.target.value)
setGender(e.target.value)
}
// input type date 요소에 날짜를 입력할 때마다 콘솔에 출력
const onChangeAge = (e) => {
console.log('나이 변경된 값 : ', e.target.value)
setAge(e.target.value)
}
// textarea 요소에 텍스트를 입력할 때마다 콘솔에 출력
const onChangeIntro = (e) => {
console.log('자기소개 변경된 값 : ', e.target.value)
setIntro(e.target.value)
}
return (
<div>
<h1>Body</h1>
{/* input 요소에 텍스트를 입력할 때마다 onChangeName 함수가 실행되도록 설정 */}
<input type="text" value={name} onChange={onChangeName} placeholder="이름" />
<div>{name}</div>
{/* select 요소에 option을 선택할 때마다 onChangeGender 함수가 실행되도록 설정 */}
<select value={gender} onChange={onChangeGender}>
<option value="남성">남성</option>
<option value="여성">여성</option>
</select>
{/* input type date 요소에 날짜를 입력할 때마다 onChangeAge 함수가 실행되도록 설정 */}
<input type="date" value={age} onChange={onChangeAge} />
{/* textarea 요소에 텍스트를 입력할 때마다 onChangeIntro 함수가 실행되도록 설정 */}
<textarea value={intro} onChange={onChangeIntro} placeholder="자기소개" />
</div>
)
}
export default InputMultiple
- 객체 형태의 상태 관리하기
- 객체 형태의 상태를 관리할 때는 useState 함수를 사용한다.
import React, { useState } from 'react'
function InputMultiple() {
// 객체 자료형으로 State를 하나 생성하고 초깃값을 설정한다.
// State 변수인 객체 state의 초기값은 모두 공백 문자열('')이며 ,
// name, gender, age, intro 속성을 가진다.
const [user, setUser] = useState({
name: '',
gender: '',
age: '',
intro: '',
})
// input 요소에 텍스트를 입력할 때마다
const handleOnChange = (e) => {
console.log('현재 수정 대상 : ', e.target.name)
console.log('수정값 : ', e.target.value)
// 구조 분해 할당을 사용하여 name 속성을 사용
const { name, value } = e.target
// setUser 함수를 사용하여 user 상태를 변경
setUser({
// 기존 user 상태를 복사하고, name 속성을 변경
...user,
// name 속성을 사용하여 user 상태를 변경
[name]: value,
})
}
return (
<div>
<h1>Body</h1>
{/* name: 모든 입력 폼에서 name 속성을 지정한다. */}
{/* value: user 객체의 name 속성을 사용한다. */}
{/* onChange: handleOnChange 함수를 사용하여 user 객체의 name 속성을 변경한다. */}
<input type="text" name="name" value={user.name} onChange={handleOnChange} placeholder="이름" />
<select name="gender" value={user.gender} onChange={handleOnChange}>
<option value="남성">남성</option>
<option value="여성">여성</option>
</select>
<input type="date" name="age" value={user.age} onChange={handleOnChange} />
<textarea name="intro" value={user.intro} onChange={handleOnChange} placeholder="자기소개" />
</div>
)
}
export default InputMultiple
- Props와 State를 사용하여 컴포넌트 관리하기
- Props와 State를 사용하여 컴포넌트를 관리할 때는 Props를 사용하여 부모 컴포넌트에서 자식 컴포넌트로 값을 전달하고, State를 사용하여 컴포넌트 내부에서 값을 관리한다.
import React, { useState } from 'react'
// user, setUser를 매개변수로 받아 사용
function InputMultiple({ user, setUser }) {
const handleOnChange = (e) => {
// 구조 분해 할당을 사용하여 name, value를 사용
const { name, value } = e.target
// setUser 함수를 사용하여 user 상태를 변경
setUser({
// 기존 user 상태를 복사하고, name 속성을 변경
...user,
// name 속성을 사용하여 user 상태를 변경
[name]: value,
})
}
return (
<div>
<h1>Body</h1>
<input type="text" name="name" value={user.name} onChange={handleOnChange} placeholder="이름" />
<select name="gender" value={user.gender} onChange={handleOnChange}>
<option value="남성">남성</option>
<option value="여성">여성</option>
</select>
<input type="date" name="age" value={user.age} onChange={handleOnChange} />
<textarea name="intro" value={user.intro} onChange={handleOnChange} placeholder="자기소개" />
</div>
)
}
function App() {
// user, setUser를 State로 생성하고 초기값을 설정
const [user, setUser] = useState({
name: '',
gender: '',
age: '',
intro: '',
})
return (
<div>
{/* user, setUser를 Props로 전달 */}
<InputMultiple user={user} setUser={setUser} />
</div>
)
}
export default App
- State와 자식 컴포넌트
- 부모의 State 값이 변하면 해당 State를 사용하는 자식 컴포넌트도 다시 렌더링된다.
- 그렇다면 부모 컴포넌트가 자식에게 State를 전달하지 않는 경우에는 어떻게 해야 할까?
- 의미 없는 리렌더가 발생하면 웹 브라우저의 성능이 저하된다.
- 이런 경우에는 React.memo를 사용하여 컴포넌트를 최적화할 수 있다.
import React, { useState } from 'react'
function InputMultiple({ user, setUser }) {
// 리렌더링 될 때마다 콘솔에 '컴포넌트 업데이트'가 출력된다.
console.log('컴포넌트 없데이트')
(...)
return (
<div>
(...)
</div>
)
}
function App() {
(...)
return (
<div>
{/* user, setUser를 Props로 전달하지 않습니다. */}
<InputMultiple />
</div>
)
}
export default App
- React.memo를 사용하여 컴포넌트 최적화하기
- React.memo를 사용하여 컴포넌트를 최적화할 때는 React.memo 함수를 사용한다.
- 이 기능은 컴포넌트의 렌더링 성능을 최적화하기 위해 사용됩니다.
- 특히, 함수형 컴포넌트에서 props의 변화가 없을 때 불필요한 리렌더링을 방지하여 성능을 향상시키는 데 유용합니다.
import React, { useState } from 'react'
// React.memo를 사용하여 컴포넌트를 최적화
const InputMultiple = React.memo(({ user, setUser }) => {
console.log('컴포넌트 업데이트')
(...)
return (
<div>
(...)
</div>
)
})
function App() {
(...)
return (
<div>
{/* user, setUser를 Props로 전달하지 않습니다. */}
<InputMultiple />
</div>
)
}
export default App
Ref 사용하기
- Ref를 이용하면 DOM 요소에 직접 접근할 수 있다.
- Ref를 사용할 때는 useRef 함수를 사용한다.
- Ref 기본 사용법
- Ref를 사용할 때는 useRef 함수를 사용한다.
- useRef 함수를 사용하여 Ref를 만들면 Ref 객체가 반환된다.
- Ref 객체를 사용하여 DOM 요소에 접근할 수 있다.
import React, { useRef } from 'react'
function Ref() {
// input 요소에 접근할 수 있는 Ref를 만든다.
const inputRef = useRef()
// 버튼을 클릭하면 입력 값을 초기화한다.
const handleReset = () => {
inputRef.current.value = ''
}
return (
<div>
<h1>Body</h1>
{/* input 요소에 Ref를 설정한다. */}
<input type="text" ref={inputRef} />
{/* 버튼을 클릭하면 handleReset 함수가 실행된다. */}
<button onClick={handleReset}>초기화</button>
</div>
)
}
export default Ref
- useRef로 입력 폼 초기화하기
- useRef 함수를 사용하여 입력 폼을 초기화할 수 있다.
import React, { useState, useRef } from 'react'
export default function App() {
const [value, setValue] = useState('')
const [error, setError] = useState('') // 에러 메시지 상태 추가
const inputRef = useRef()
const handleReset = () => {
setValue('') // 상태를 사용하여 입력 값을 관리
setError('') // 초기화 시 에러 메시지도 초기화
}
const handleChange = (e) => {
setValue(e.target.value)
if (e.target.value.length < 5) {
setError('5글자 이상 입력해주세요.') // 5글자 미만일 때 에러 메시지 설정
} else {
setError('') // 충분한 글자가 입력되면 에러 메시지 제거
}
}
const handleClick = () => {
if (value.length < 5) {
inputRef.current.focus() // 5글자 미만일 경우 포커스 이동
} else {
alert('작성 완료') // 5글자 이상일 경우 작성 완료 처리
setValue('') // 입력값 초기화
setError('') // 에러 메시지 초기화
}
}
return (
<div>
<h1>Body</h1>
<input
type="text"
value={value} // input 요소의 값으로 상태를 사용
onChange={handleChange} // 입력 시 handleChange 함수 실행
ref={inputRef}
/>
{error && <div style={{ color: 'red' }}>{error}</div>} {/* 에러 메시지 표시 */}
<button onClick={handleReset}>초기화</button>
<button onClick={handleClick}>작성 완료</button>
</div>
)
}
'Front > React' 카테고리의 다른 글
useEffect, 생명주기 - React 배우기 (0) | 2024.03.11 |
---|---|
React 카운터 앱 만들기 - component, useState (1) | 2024.03.04 |
API 통신 - react 배우기 (0) | 2023.11.16 |
React GitHub 배포, Netlify 배포 (0) | 2023.11.13 |
React Library (0) | 2023.11.06 |