상태(State)란 컴포넌트가 가질 수 있는 동적인 데이터를 의미합니다.
useState 기본 문법 설명
const [state, setState] = useState(initialValue);
// - state: 현재 상태 값
// - setState: 상태를 변경하는 함수
// - initialValue: 초기 상태 값
리액트 컴포넌트는 입력과 출력이 있는데 prop를 통해 입력된 데이터를 우리가 만든 컴포넌트 함수가 처리해서 retrun을 통해 출력한다.
props는 컴포넌트를 사용하는 외부자를 위한 데이터이다.

state는 props와 비슷하지만 컴포넌트 내부에서 선언하며 내부에서 값을 변경할 수 있다.
state는 컴포넌트 자신을 위한 데이터이다.

// useState의 반환값
const [state변수, state변경함수] = useState(초기값);
// useState는 항상 2개의 요소를 가진 배열을 반환합니다
const array = useState('winter');
// array = ['winter', function()]
// 이것을 풀어서 쓰면
const name = array[0]; // 'winter'
const setName = array[1]; // setState 함수
// 구조 분해 할당으로 한 번에 쓰면
const [name, setName] = useState('winter');
// App.js
import React from 'react';
function App() {
let name = 'winter'; // name 변수에 'winter'라는 값을 저장한다.
// changeName() 함수를 정의한다.
function changeName() {
// name의 값이 'winter'이면 'fall'로, 'fall'이면 'winter'로 변경한다.
name = name === 'winter' ? 'fall' : 'winter';
console.log(name); // name의 값을 출력한다.
}
return (
// name의 값을 출력한다.
// 버튼을 클릭하면 changeName() 함수를 실행한다.
<div className='root'>
<h1>{name}</h1>
<button onClick={changeName}>Name Change</button>
</div>
);
}
export default App;
// App.js
import React from 'react';
function App() {
let name = 'winter'; // name 변수에 'winter'라는 값을 저장한다.
// changeName() 함수를 정의한다.
function changeName() {
// name의 값이 'winter'이면 'fall'로, 'fall'이면 'winter'로 변경한다.
name = name === 'winter' ? 'fall' : 'winter';
console.log(name); // name의 값을 출력한다.
document.querySelector('h1').innerText = name; // h1 태그의 텍스트를 name의 값으로 변경한다.
}
return (
<div className='root'>
<h1>{name}</h1>
<button onClick={changeName}>Name Change</button>
</div>
);
}
export default App;
// App.js
// useState를 불러온다.
import React, { useState } from 'react';
function App() {
// name : 상태의 이름, setName : 상태를 변경하는 함수
// useState('winter') : 상태의 초기값
const [name, setName] = useState('winter');
// 배열의 구조 분해 할당
// const name = useState('winter')[0];
// const setName = useState('winter')[1];
// useState('winter') : 상태의 초기값
function changeName() {
// 상태를 변경하는 함수(setName)를 사용해 name의 값을 변경한다.
// name의 값이 'winter'이면 'fall'로, 'fall'이면 'winter'로 변경한다.
// 삼항 연산자 : 조건 ? 참일 때 값 : 거짓일 때 값
setName(name === 'winter' ? 'fall' : 'winter');
}
return (
// button을 클릭하면 changeName() 함수를 등록합니다.
<div className='root'>
<h1>{name}</h1>
<button onClick={changeName}>Name Change</button>
</div>
);
}
export default App;
// App.js
import React, { useState } from 'react'; // useState를 불러온다.
function App() {
const [number, setNumber] = useState(0);
function increase() {
setNumber(number + 1);
}
function decrease() {
setNumber(number - 1);
}
return (
<div className='root'>
<h1>{number}</h1>
<button onClick={increase}>+</button>
<button onClick={decrease}>-</button>
</div>
);
}
export default App;
<button
onClick={() => {
setIsOpen(!isOpen);
}}
>
{/* {isOpen ? 'x' : '='} */}
{isOpen ? <IoCloseSharp /> : <FaBars />}
</button>
'use client';
import React, { useState } from 'react';
import { TbTicket } from 'react-icons/tb'; // 컬쳐 아이콘
import { GiTreehouse } from 'react-icons/gi'; // 한적한 시골
import { MdOutlinePhotoCamera } from 'react-icons/md'; // 최고의 전망
import { BiHome } from 'react-icons/bi'; // 한옥
const Sort = () => {
const sortArr = [
{ value: '컬쳐 아이콘', icon: <TbTicket /> },
{ value: '한적한 시골', icon: <GiTreehouse /> },
{ value: '최고의 전망', icon: <MdOutlinePhotoCamera /> },
{ value: '한옥', icon: <BiHome /> },
];
const [selected, setSelected] = useState(0);
return (
<div className='max-w-6xl mx-auto px-4'>
<div
className='flex justify-between items-center gap-8 border-b'
role='tablist'
aria-label='숙소 카테고리'
>
{sortArr.map((item, index) => (
<button
key={index}
onClick={() => setSelected(index)}
className={`
flex flex-col items-center justify-center
py-4 gap-2 flex-1
transition-all duration-200 ease-in-out
focus:outline-none
${selected === index ? 'text-black border-b-2 border-black' : 'text-gray-500 hover:text-black hover:border-b-2 hover:border-gray-300'}
`}
role='tab'
aria-selected={selected === index}
>
<span
className='text-2xl'
aria-hidden='true'
>
{item.icon}
</span>
<span className='text-xs font-medium whitespace-nowrap'>{item.value}</span>
</button>
))}
</div>
<div className='mt-4'>
{sortArr.map((item, index) => (
<div
key={index}
role='tabpanel'
aria-hidden={selected !== index}
className={`
transition-all duration-200 ease-in-out
${selected === index ? 'block' : 'hidden'}
`}
>
{item.value} 관련 숙소가 표시됩니다.
</div>
))}
</div>
</div>
);
};
export default Sort;
// App.js
import React, { useState } from 'react'; // useState를 불러온다.
function App() {
// 상태를 정의한다. text는 상태의 이름, setText는 상태를 변경하는 함수이다.
// useState('')은 상태의 초기값이다.
const [text, setText] = useState('');
// input의 값을 변경했을 때 실행되는 함수이다.
// e.target.value : input의 value 속성의 값을 가져온다.
function handleChange(e) {
setText(e.target.value); // setText() 함수를 사용해 text의 값을 변경한다.
// text 상태 값이 변경되면 컴포넌트가 다시 렌더링되기 때문에 text 상태 값이 출력된다.
}
return (
// input의 값을 출력한다.
// input의 값이 변경되면 handleChange() 함수를 실행한다.
<div className='root'>
<input
type='text'
value={text}
onChange={handleChange}
/>
<p>{text}</p>
</div>
);
}
export default App;
import { NavLink } from 'react-router-dom';
const Navigation = () => {
// NavLink의 className을 위한 공통 함수
const getLinkStyle = ({ isActive }) => {
return `
transition-colors duration-200
hover:text-yellow-500
${isActive ? 'text-yellow-500' : 'text-white'}
`;
};
return (
<nav>
<ul className='flex space-x-4'>
<li>
<NavLink
to='/'
className={getLinkStyle}
>
Home
</NavLink>
</li>
<li>
<NavLink
to='/about'
className={getLinkStyle}
>
About
</NavLink>
</li>
<li>
<NavLink
to='/contact'
className={getLinkStyle}
>
Contact
</NavLink>
</li>
</ul>
</nav>
);
};
export default Navigation;