코딩앙마님의 리액트 강의를 보고 정리한 내용입니다.
https://www.youtube.com/watch?v=DuJC2ATdGtw&list=PLZKTXPmaJk8J_fHAzPLH8CJ_HO_M33e7-&index=8
create-react-app
기본 폴더 설명

node_modules 폴더는 이 프로젝트를 실행할 때 사용되는 dependencies 모듈들이 모여있는 것이다. 여기에 설치되어 있는 내용들은 package.json 파일에 기록되어 있다. 이 폴더가 없으면 프로젝트를 진행할 수 없는데, 폴더가 없는 경우 npm install을 하면 그대로 다시 설치할 수 있다.
그래서 이 폴더는 내용도 많고 무겁기 때문에 깃에 올리지 않는다. 하지만 package.json에 내용이 기록되어 있기 때문에 다른 개발자가 동일한 환경을 구축할 수 있어서 문제가 없다.
public 폴더에는 index.html 파일이 있다. 이 html 파일 안에는 id=root의 div 태그가 있는데 이 태그 내의 내용이 실행이 되어 dom에 구축이 되는 것이다.
대부분의 작업은 src 폴더 내에서 진행되게 된다. App.js 파일에 원하는 내용을 적으면 바로 적용되는데 이것을 Hot Module Replacement(HMR)이라고 한다.
▷Hot Module Replacement(HMR)
: HMR은 브라우저를 새로 고치지 않아도 웹팩으로 빌드한 결과물이 웹 애플리케이션에 실시간으로 반영되도록 하는 것.
npm start와 같은 명령어는 package.json에 명시되어 있다.

start는 개발 모드로 프로그램을 실행
build는 실제 배포 모드로 만듦
eject는 내부 설정 파일을 꺼내는 역할을 한다. 웹팩이나 바벨 설정을 변경하고 싶을 때 사용한다.
component
:리액트로 만들어진 페이지는 컴포넌트로 구성되어 있다. 페이지의 각 부분을 컴포넌트로 만들어서 조립하는 것.
처음에는 App.js 컴포넌트만 존재하는데 함수로 작성되어 함수 컴포넌트라고 부른다. 이 함수 컴포넌트가 반환하는 값은 return 안에 있는 html처럼 생긴 JSX(JavaScript XML)이다.
function App() {
const name = "Tom";
const naver = {
name: "네이버",
url:"https://naver.com",
}
return (
<div className="App">
<h1
style={
{color: "red",
backgroundColor: "green",
}
}
>
Hello, {name}. <p>{2 + 3}</p>
</h1>
<a href={naver.url}>{naver.name}</a>
</div>
);
}
-속성을 적을 땐 {} 중괄호를 사용한다.
-style을 작성할 땐 객체 형태로 작성한다.
-return 밖에서 변수나 객체를 선언하고 return 안에서 중괄호로 변수를 불러오면 사용할 수 있다.
또한 중괄호 내에서 { 2+ 3} 이렇게 작성하면 페이지에는 계산된 값이 출력된다.
이렇게 문자열이나 숫자는 사용 가능하지만불리언 타입이나 객체 자체를 출력하지 못한다.

component 만들기
화면에 Hello를 출력하는 컴포넌트를 직접 만들어보자.
component 폴더에 Hello.js를 생성한다.(첫 글자는 대문자)
그리고 아래의 내용을 적어준다.
const Hello = function(){
return <p>Hello</p>
}
export default Hello;
이는 class로도 만들 수 있으며 화살표 함수로도 만들 수 있다.
//1
class Hello extends Component {
...
}
//2
const Hello = () => {
...
}
//3
export default function Hello(){
...
}
맨 처음 방법과 위의 3가지 방법 모두 컴포넌트를 만드는 방법들이다.
그다음 App.js에서 Hello 컴포넌트를 불러오면 된다.
import './App.css';
import Hello from './component/Hello';
function App() {
return (
<div className="App">
<Hello />
</div>
);
}
export default App;
import로 Hello.js 파일을 연결해주고
다른 태그 쓰듯이 <Hello></Hello>를 사용해주면 된다. 만약 내용이 없는 경우 <Hello/>로 써주면 코드가 더욱 간결해진다.
이와 똑같이 Welcome 컴포넌트를 만들어서 App 컴포넌트에 연결할 수 있다.
이번엔 World 컴포넌트를 만들어서 Hello에서 불러와보자.
export default function World(){
return <h3>World!</h3>
}
이렇게 World 컴포넌트를 만들고
import World from "./World";
const Hello = function(){
return (
<div>
<h1>Hello</h1>
<World />
</div>
);
}
export default Hello;
Hello 컴포넌트에서 World를 연결해서 불러와주면 된다.
여기서 div 태그를 제거하면 에러가 나는데 그 이유는 컴포넌트는 하나의 태그만 만들 수 있기 때문이다. 따라서 내용이 하나의 태그로 감싸져야 한다.
전체 컴포넌트의 구조를 보면 App컴포넌트에는 Hello 컴포넌트와 Welcome 컴포넌트가 그리고 Hello 컴포넌트에는 World 컴포넌트가 포함되어 있다.

css작성법
1. 인라인 스타일 사용하기
: 객체 형태로 작성해야 한다. 키는 속성을, value는 속성 값을 적는다.
그리고 속성에 -가 쓰이는 것들은 카멜 케이스로 작성해야 한다. (border-right => borderRight)
<h1 style ={
{
color: '#f00',
borderRight: '2px solid #000',
opacity: 0.5,
}
}
숫자는 그냥 써도 되지만 px이나 다른 것들은 문자열로 작성해야 한다.
하지만 웬만한 경우에는 인라인 스타일을 사용하지 않기 때문에 사용을 지양하는 것이 좋다.
2. index.css, App.css 파일 활용하기
index.css에는 전체 프로젝트에 영향을 미치는 스타일이, App.css 는 App 컴포넌트 한정으로 영향을 미치는 스타일이 들어가 있다.
하지만! App.css라고 해서 App 컴포넌트에만 영향을 미치는 것이 아니다.
App 컴포넌트와 Hello 컴포넌트에 각각 다른 색의 박스를 만들어보자.
//Hello.js
import World from "./World";
import "./Hello.css"
const Hello = function(){
return (
<div>
<h1>Hello</h1>
<World />
<div className="box">Hello</div>
</div>
);
}
export default Hello;
//App.js
import './App.css';
import Hello from './component/Hello';
import Welcome from './component/Welcome';
function App() {
return (
<div className="App">
<Hello />
<Welcome />
<div className="box">App</div>
</div>
);
}
export default App;
//App.css
.box{
width: 100px;
height: 100px;
background-color: red;
}
//Hello.css
.box{
width: 100px;
height: 50px;
background-color: blue;
}
이렇게 App.js 에는 App.css와 Hello.js가 연결되어 있고 Hello.js에는 Hello.css가 연결되어 있다. 결과적으로

이렇게 둘 다 Hello.css가 적용된 것을 알 수 있다. 어째서 App 컴포넌트에도 적용이 된 것일까?
그 이유는 css가 따로 적용되는 것이 아니라 전체 header style 태그 안에 저장되기 때문이다.

따라서 전체 box에 동일한 css가 적용될 수밖에 없다.
3. css 모듈 사용
그럼 이제 css가 따로 적용될 수 있도록 각 컴포넌트에 특화된 css를 작성해보자.
css 모듈을 활용할 것이기 때문에 컴포넌트 이름.module.css 파일을 만들어 준다.

그다음 Hello.css 가 아니라 Hello.module.css를 styles로 연결해서 Hello.js에서 불러온다.
import World from "./World";
import styles from "./Hello.module.css"
const Hello = function(){
return (
<div>
<h1>Hello</h1>
<World />
<div className={styles.box}>Hello</div>
</div>
);
}
export default Hello;
그리고 클래스 네임을 작성할 땐 문자열이 아니라 중괄호를 사용해서 styles.box로 지정한다.
App.js 역시 똑같은 작업을 해주면

이렇게 각각 다른 css가 적용되는 것을 볼 수 있다.
똑같은 클래스 이름임에도 다른 css를 적용할 수 있는 이유는

css 모듈에 의해 독자적인 클래스 이름이 부여되어 적용되기 때문이다.
이벤트 처리(Handling Events)
버튼을 클릭하면 이름과 나이가 나오도록 해보자.
이벤트를 만드는 방법은 두 가지가 있는데
첫 번째는 함수를 따로 만들어놓고 onClick으로 그 함수를 호출하는 방법과
두 번째는 onClick에 함수를 직접 작성하는 방법이다.
const Hello = function(){
function showName(){
console.log("Mike");
}
return (
<div>
<h1>Hello</h1>
<button onClick={showName}>Show name</button> //첫 번째 방법
<button onClick={ //두 번째 방법
()=>{
console.log("30");
}}
>Show age</button>
</div>
);
}
만약 함수가 인자를 받으려면?
const Hello = function(){
function showAge(age){
console.log(age);
}
return (
<div>
<h1>Hello</h1>
<button onClick={
()=>{
showAge(30);
}}
>Show age</button>
</div>
);
}
이렇게 인자를 전달할 수 있다. onClick={showAge(30)}이 아니라 onClick={() => {showAge(30)}}을 하는 이유는 첫 번째 방법으로는 매개변수를 넘길 수 없기 때문이다. 첫 번째 방법에서는 showAge(30)의 리턴 값이 들어간다. 즉 undefined이 들어가게 되기 때문에 매개변수를 전달하려면 두 번째 방법을 사용해야 한다.
state
:컴포넌트가 가지고 있는 속성 값
const Hello = function(){
let name = "Mike";
function changeName(){
name = name === "Mike" ? "Jane" : "Mike";
console.log(name);
}
return (
<div>
<h1>state</h1>
<h2>{name}</h2>
<button onClick={changeName}>Change</button>
</div>
);
}
이렇게 이름을 바꾸는 코드를 작성했을 때 콘솔에 찍어보면 정상적으로 이름이 바뀌지만 화면에서 출력되는 값은 변화가 없다. 만약 바닐라 자바스크립트였다면,
document.queryselector("#name").innerText = name;
이런 식으로 아이디 값을 줘서 DOM을 직접 업데이트해줘야 한다.
현재 name이라는 변수는 state 값이 아니라서 리액트에서 관리하고 있지 않다. 그래서 값이 변경되어도 리액트가 모르는 것. 이때 사용하는 것이useState라는 hook이다.
import { useState } from "react";
const Hello = function(){
const [name, setName] = useState("Mike");
function changeName(){
const newName = name === "Mike" ? "Jane" : "Mike";
setName(newName);
}
return (
<div>
<h1>state</h1>
<h2>{name}</h2>
<button onClick={changeName}>Change</button>
</div>
);
}
useState를 import 해주어야 사용할 수 있다.
import 해준 후,
useState는 배열을 반환한다. 첫 번째 값은 name이라는 state이고 두 번째는 state를 변경해주는 함수이다. 그래서 setName 함수를 통해서 state가 바뀌면 리액트는 Hello 컴포넌트를 다시 랜더링 한다.
useState의 괄호 안에는 초기 값이 들어간다.
import { useState } from "react";
const Hello = function(){
const [name, setName] = useState("Mike");
return (
<div>
<h1>state</h1>
<h2>{name}</h2>
<button onClick={() => {
setName(name === "Mike" ? "Jane" : "Mike");
}}
>
Change
</button>
</div>
);
}
이 것 역시 위의 코드와 동일하게 작동한다. 여러 형태로 코드를 작성할 수 있다.
props
:property, 속성 값
function App() {
return (
<div className="App">
<Hello age={10} />
<Hello age={20} />
<Hello age={30} />
</div>
);
}
App 컴포넌트에서 props(속성)으로 age를 전달하면,
const Hello = function(props){
console.log(props);
...
}
이렇게 Hello 컴포넌트에서 확인해봤을 때 콘솔에 {age: 10}.. 이 찍힌다.
<h2>{name}({props.age}세)</h2>
그래서 Hello 컴포넌트에서 이렇게 props 값을 받아오면

각 props 값이 출력된다.
이 값은 컴포넌트 내부에서 변경할 수 없다. 넘겨받은 그대로 사용해야 한다.
만약 변경하고 싶다면 넘겨받은 props의 값을 state로 만들어서 변경해야 한다.
const Hello = function(props){
const [name, setName] = useState("Mike");
const [age, setAge] = useState(props.age);
return (
<div>
<h2>{name}({age})</h2>
<button onClick={() => {
setName(name === "Mike" ? "Jane" : "Mike");
setAge(age + 1)
}}>Change</button>
</div>
);
}
이렇게 초기 값으로 props의 age를 받는 state 값을 생성해서 버튼을 누를 때마다 1씩 증가시킬 수 있다.

이것은 넘겨받은 props 값을 변경하는 것이 아니라 그 props 값으로 만든 state 값을 변경하는 것이다. props를 변경하려고 하며 에러가 난다.
현재 props 값은 age 만 받아오고 있기 때문에
const Hello = function({ age }){
const [name, setName] = useState("Mike");
return (
<div>
<h2>{name}({age})</h2>
이렇게도 표현이 가능하다.
컴포넌트가 가지고 있는 state를 다른 컴포넌트에게도 넘겨줄 수 있다.
UserName이라는 컴포넌트를 새로 만드는데 이 컴포넌트는 이름을 받아서 그 이름을 출력할 것이다.
export default function UserName ({name}){
return <p>Hello, {name}</p>
}
이렇게 만든 UserName 컴포넌트를 Hello 컴포넌트에서 사용할 것이다.
import { useState } from "react";
import UserName from "./UserName";
const Hello = function({ age }){
const [name, setName] = useState("Mike");
return (
<div>
<h2>{name}({age})</h2>
<UserName name={name} />
<button onClick={() => {
setName(name === "Mike" ? "Jane" : "Mike");
}}>Change</button>
</div>
);
}
export default Hello;
이렇게 UserName을 태그로 사용하면서 name props에다가 현재 Hello에 저장되어 있는 state name 값을 전달한다.
'개발 공부 > React' 카테고리의 다른 글
React #9 [json-server, REST API, custom hook] (0) | 2022.08.27 |
---|---|
React #8 [json, 리액트 라우터] (0) | 2022.08.26 |
React #6 [update, delete] (0) | 2022.08.09 |
React #5 [props와 state, create, push와 concat] (0) | 2022.07.16 |
React #4 [event 만들기, bind, setState] (0) | 2022.07.13 |
코딩앙마님의 리액트 강의를 보고 정리한 내용입니다.
https://www.youtube.com/watch?v=DuJC2ATdGtw&list=PLZKTXPmaJk8J_fHAzPLH8CJ_HO_M33e7-&index=8
create-react-app
기본 폴더 설명

node_modules 폴더는 이 프로젝트를 실행할 때 사용되는 dependencies 모듈들이 모여있는 것이다. 여기에 설치되어 있는 내용들은 package.json 파일에 기록되어 있다. 이 폴더가 없으면 프로젝트를 진행할 수 없는데, 폴더가 없는 경우 npm install을 하면 그대로 다시 설치할 수 있다.
그래서 이 폴더는 내용도 많고 무겁기 때문에 깃에 올리지 않는다. 하지만 package.json에 내용이 기록되어 있기 때문에 다른 개발자가 동일한 환경을 구축할 수 있어서 문제가 없다.
public 폴더에는 index.html 파일이 있다. 이 html 파일 안에는 id=root의 div 태그가 있는데 이 태그 내의 내용이 실행이 되어 dom에 구축이 되는 것이다.
대부분의 작업은 src 폴더 내에서 진행되게 된다. App.js 파일에 원하는 내용을 적으면 바로 적용되는데 이것을 Hot Module Replacement(HMR)이라고 한다.
▷Hot Module Replacement(HMR)
: HMR은 브라우저를 새로 고치지 않아도 웹팩으로 빌드한 결과물이 웹 애플리케이션에 실시간으로 반영되도록 하는 것.
npm start와 같은 명령어는 package.json에 명시되어 있다.

start는 개발 모드로 프로그램을 실행
build는 실제 배포 모드로 만듦
eject는 내부 설정 파일을 꺼내는 역할을 한다. 웹팩이나 바벨 설정을 변경하고 싶을 때 사용한다.
component
:리액트로 만들어진 페이지는 컴포넌트로 구성되어 있다. 페이지의 각 부분을 컴포넌트로 만들어서 조립하는 것.
처음에는 App.js 컴포넌트만 존재하는데 함수로 작성되어 함수 컴포넌트라고 부른다. 이 함수 컴포넌트가 반환하는 값은 return 안에 있는 html처럼 생긴 JSX(JavaScript XML)이다.
function App() {
const name = "Tom";
const naver = {
name: "네이버",
url:"https://naver.com",
}
return (
<div className="App">
<h1
style={
{color: "red",
backgroundColor: "green",
}
}
>
Hello, {name}. <p>{2 + 3}</p>
</h1>
<a href={naver.url}>{naver.name}</a>
</div>
);
}
-속성을 적을 땐 {} 중괄호를 사용한다.
-style을 작성할 땐 객체 형태로 작성한다.
-return 밖에서 변수나 객체를 선언하고 return 안에서 중괄호로 변수를 불러오면 사용할 수 있다.
또한 중괄호 내에서 { 2+ 3} 이렇게 작성하면 페이지에는 계산된 값이 출력된다.
이렇게 문자열이나 숫자는 사용 가능하지만불리언 타입이나 객체 자체를 출력하지 못한다.

component 만들기
화면에 Hello를 출력하는 컴포넌트를 직접 만들어보자.
component 폴더에 Hello.js를 생성한다.(첫 글자는 대문자)
그리고 아래의 내용을 적어준다.
const Hello = function(){
return <p>Hello</p>
}
export default Hello;
이는 class로도 만들 수 있으며 화살표 함수로도 만들 수 있다.
//1
class Hello extends Component {
...
}
//2
const Hello = () => {
...
}
//3
export default function Hello(){
...
}
맨 처음 방법과 위의 3가지 방법 모두 컴포넌트를 만드는 방법들이다.
그다음 App.js에서 Hello 컴포넌트를 불러오면 된다.
import './App.css';
import Hello from './component/Hello';
function App() {
return (
<div className="App">
<Hello />
</div>
);
}
export default App;
import로 Hello.js 파일을 연결해주고
다른 태그 쓰듯이 <Hello></Hello>를 사용해주면 된다. 만약 내용이 없는 경우 <Hello/>로 써주면 코드가 더욱 간결해진다.
이와 똑같이 Welcome 컴포넌트를 만들어서 App 컴포넌트에 연결할 수 있다.
이번엔 World 컴포넌트를 만들어서 Hello에서 불러와보자.
export default function World(){
return <h3>World!</h3>
}
이렇게 World 컴포넌트를 만들고
import World from "./World";
const Hello = function(){
return (
<div>
<h1>Hello</h1>
<World />
</div>
);
}
export default Hello;
Hello 컴포넌트에서 World를 연결해서 불러와주면 된다.
여기서 div 태그를 제거하면 에러가 나는데 그 이유는 컴포넌트는 하나의 태그만 만들 수 있기 때문이다. 따라서 내용이 하나의 태그로 감싸져야 한다.
전체 컴포넌트의 구조를 보면 App컴포넌트에는 Hello 컴포넌트와 Welcome 컴포넌트가 그리고 Hello 컴포넌트에는 World 컴포넌트가 포함되어 있다.

css작성법
1. 인라인 스타일 사용하기
: 객체 형태로 작성해야 한다. 키는 속성을, value는 속성 값을 적는다.
그리고 속성에 -가 쓰이는 것들은 카멜 케이스로 작성해야 한다. (border-right => borderRight)
<h1 style ={
{
color: '#f00',
borderRight: '2px solid #000',
opacity: 0.5,
}
}
숫자는 그냥 써도 되지만 px이나 다른 것들은 문자열로 작성해야 한다.
하지만 웬만한 경우에는 인라인 스타일을 사용하지 않기 때문에 사용을 지양하는 것이 좋다.
2. index.css, App.css 파일 활용하기
index.css에는 전체 프로젝트에 영향을 미치는 스타일이, App.css 는 App 컴포넌트 한정으로 영향을 미치는 스타일이 들어가 있다.
하지만! App.css라고 해서 App 컴포넌트에만 영향을 미치는 것이 아니다.
App 컴포넌트와 Hello 컴포넌트에 각각 다른 색의 박스를 만들어보자.
//Hello.js
import World from "./World";
import "./Hello.css"
const Hello = function(){
return (
<div>
<h1>Hello</h1>
<World />
<div className="box">Hello</div>
</div>
);
}
export default Hello;
//App.js
import './App.css';
import Hello from './component/Hello';
import Welcome from './component/Welcome';
function App() {
return (
<div className="App">
<Hello />
<Welcome />
<div className="box">App</div>
</div>
);
}
export default App;
//App.css
.box{
width: 100px;
height: 100px;
background-color: red;
}
//Hello.css
.box{
width: 100px;
height: 50px;
background-color: blue;
}
이렇게 App.js 에는 App.css와 Hello.js가 연결되어 있고 Hello.js에는 Hello.css가 연결되어 있다. 결과적으로

이렇게 둘 다 Hello.css가 적용된 것을 알 수 있다. 어째서 App 컴포넌트에도 적용이 된 것일까?
그 이유는 css가 따로 적용되는 것이 아니라 전체 header style 태그 안에 저장되기 때문이다.

따라서 전체 box에 동일한 css가 적용될 수밖에 없다.
3. css 모듈 사용
그럼 이제 css가 따로 적용될 수 있도록 각 컴포넌트에 특화된 css를 작성해보자.
css 모듈을 활용할 것이기 때문에 컴포넌트 이름.module.css 파일을 만들어 준다.

그다음 Hello.css 가 아니라 Hello.module.css를 styles로 연결해서 Hello.js에서 불러온다.
import World from "./World";
import styles from "./Hello.module.css"
const Hello = function(){
return (
<div>
<h1>Hello</h1>
<World />
<div className={styles.box}>Hello</div>
</div>
);
}
export default Hello;
그리고 클래스 네임을 작성할 땐 문자열이 아니라 중괄호를 사용해서 styles.box로 지정한다.
App.js 역시 똑같은 작업을 해주면

이렇게 각각 다른 css가 적용되는 것을 볼 수 있다.
똑같은 클래스 이름임에도 다른 css를 적용할 수 있는 이유는

css 모듈에 의해 독자적인 클래스 이름이 부여되어 적용되기 때문이다.
이벤트 처리(Handling Events)
버튼을 클릭하면 이름과 나이가 나오도록 해보자.
이벤트를 만드는 방법은 두 가지가 있는데
첫 번째는 함수를 따로 만들어놓고 onClick으로 그 함수를 호출하는 방법과
두 번째는 onClick에 함수를 직접 작성하는 방법이다.
const Hello = function(){
function showName(){
console.log("Mike");
}
return (
<div>
<h1>Hello</h1>
<button onClick={showName}>Show name</button> //첫 번째 방법
<button onClick={ //두 번째 방법
()=>{
console.log("30");
}}
>Show age</button>
</div>
);
}
만약 함수가 인자를 받으려면?
const Hello = function(){
function showAge(age){
console.log(age);
}
return (
<div>
<h1>Hello</h1>
<button onClick={
()=>{
showAge(30);
}}
>Show age</button>
</div>
);
}
이렇게 인자를 전달할 수 있다. onClick={showAge(30)}이 아니라 onClick={() => {showAge(30)}}을 하는 이유는 첫 번째 방법으로는 매개변수를 넘길 수 없기 때문이다. 첫 번째 방법에서는 showAge(30)의 리턴 값이 들어간다. 즉 undefined이 들어가게 되기 때문에 매개변수를 전달하려면 두 번째 방법을 사용해야 한다.
state
:컴포넌트가 가지고 있는 속성 값
const Hello = function(){
let name = "Mike";
function changeName(){
name = name === "Mike" ? "Jane" : "Mike";
console.log(name);
}
return (
<div>
<h1>state</h1>
<h2>{name}</h2>
<button onClick={changeName}>Change</button>
</div>
);
}
이렇게 이름을 바꾸는 코드를 작성했을 때 콘솔에 찍어보면 정상적으로 이름이 바뀌지만 화면에서 출력되는 값은 변화가 없다. 만약 바닐라 자바스크립트였다면,
document.queryselector("#name").innerText = name;
이런 식으로 아이디 값을 줘서 DOM을 직접 업데이트해줘야 한다.
현재 name이라는 변수는 state 값이 아니라서 리액트에서 관리하고 있지 않다. 그래서 값이 변경되어도 리액트가 모르는 것. 이때 사용하는 것이useState라는 hook이다.
import { useState } from "react";
const Hello = function(){
const [name, setName] = useState("Mike");
function changeName(){
const newName = name === "Mike" ? "Jane" : "Mike";
setName(newName);
}
return (
<div>
<h1>state</h1>
<h2>{name}</h2>
<button onClick={changeName}>Change</button>
</div>
);
}
useState를 import 해주어야 사용할 수 있다.
import 해준 후,
useState는 배열을 반환한다. 첫 번째 값은 name이라는 state이고 두 번째는 state를 변경해주는 함수이다. 그래서 setName 함수를 통해서 state가 바뀌면 리액트는 Hello 컴포넌트를 다시 랜더링 한다.
useState의 괄호 안에는 초기 값이 들어간다.
import { useState } from "react";
const Hello = function(){
const [name, setName] = useState("Mike");
return (
<div>
<h1>state</h1>
<h2>{name}</h2>
<button onClick={() => {
setName(name === "Mike" ? "Jane" : "Mike");
}}
>
Change
</button>
</div>
);
}
이 것 역시 위의 코드와 동일하게 작동한다. 여러 형태로 코드를 작성할 수 있다.
props
:property, 속성 값
function App() {
return (
<div className="App">
<Hello age={10} />
<Hello age={20} />
<Hello age={30} />
</div>
);
}
App 컴포넌트에서 props(속성)으로 age를 전달하면,
const Hello = function(props){
console.log(props);
...
}
이렇게 Hello 컴포넌트에서 확인해봤을 때 콘솔에 {age: 10}.. 이 찍힌다.
<h2>{name}({props.age}세)</h2>
그래서 Hello 컴포넌트에서 이렇게 props 값을 받아오면

각 props 값이 출력된다.
이 값은 컴포넌트 내부에서 변경할 수 없다. 넘겨받은 그대로 사용해야 한다.
만약 변경하고 싶다면 넘겨받은 props의 값을 state로 만들어서 변경해야 한다.
const Hello = function(props){
const [name, setName] = useState("Mike");
const [age, setAge] = useState(props.age);
return (
<div>
<h2>{name}({age})</h2>
<button onClick={() => {
setName(name === "Mike" ? "Jane" : "Mike");
setAge(age + 1)
}}>Change</button>
</div>
);
}
이렇게 초기 값으로 props의 age를 받는 state 값을 생성해서 버튼을 누를 때마다 1씩 증가시킬 수 있다.

이것은 넘겨받은 props 값을 변경하는 것이 아니라 그 props 값으로 만든 state 값을 변경하는 것이다. props를 변경하려고 하며 에러가 난다.
현재 props 값은 age 만 받아오고 있기 때문에
const Hello = function({ age }){
const [name, setName] = useState("Mike");
return (
<div>
<h2>{name}({age})</h2>
이렇게도 표현이 가능하다.
컴포넌트가 가지고 있는 state를 다른 컴포넌트에게도 넘겨줄 수 있다.
UserName이라는 컴포넌트를 새로 만드는데 이 컴포넌트는 이름을 받아서 그 이름을 출력할 것이다.
export default function UserName ({name}){
return <p>Hello, {name}</p>
}
이렇게 만든 UserName 컴포넌트를 Hello 컴포넌트에서 사용할 것이다.
import { useState } from "react";
import UserName from "./UserName";
const Hello = function({ age }){
const [name, setName] = useState("Mike");
return (
<div>
<h2>{name}({age})</h2>
<UserName name={name} />
<button onClick={() => {
setName(name === "Mike" ? "Jane" : "Mike");
}}>Change</button>
</div>
);
}
export default Hello;
이렇게 UserName을 태그로 사용하면서 name props에다가 현재 Hello에 저장되어 있는 state name 값을 전달한다.
'개발 공부 > React' 카테고리의 다른 글
React #9 [json-server, REST API, custom hook] (0) | 2022.08.27 |
---|---|
React #8 [json, 리액트 라우터] (0) | 2022.08.26 |
React #6 [update, delete] (0) | 2022.08.09 |
React #5 [props와 state, create, push와 concat] (0) | 2022.07.16 |
React #4 [event 만들기, bind, setState] (0) | 2022.07.13 |