컴포넌트 내부에서 바뀔 수 있는 값
- JS의 변수나 상수를 사용하지 않고 state를 쓰는 목적은 UI(엘리먼트)를 바꾸기 위함!
State를 만들 때는 useState()를 사용한다. <- 리액트에서의 함수 형태
useState('initial Value'); // 초기값을 넣는다.
// -> 배열형태로 두 가지 값을 return한다.
// -> [state(초기값으로 생성된 state), setstate(state를 다룰 수 있는 메서드로, 앞에 set을 붙여준다.)]
// 구조분해할당으로 state를 만들면 아래와 같은 형태가 된다.
const [state, setstate] = useState('initial Value');
import React from 'react';
function App() {
const [count, setCount] = useState(0); // 초기값이 0인 카운트
const [todoList, setTodoList] = useState([]); // 초기값이 빈 배열인 todolist
return <div></div>
}
export default App;
import React, { useState } from 'react';
function App() {
// useState 초기값으로 '김할아버지' 설정
const [name, setName] = useState('김할아버지')
return (
<div>
{name}
// 줄바꿈 태그
<br />
// 버튼에 onClick을 먹이고 함수 setName으로 '박할아버지' 설정
<button onClick={function(){
setName('박할아버지')
}}>클릭</button>
</div>
);
}
export default App;
// -> 클릭을 했을 때, '김할아버지'가 '박할아버지'로 변경됨
import { useState } from 'react';
function App() {
// 빈 문자열이 초기값인 useState 설정
const [fruit, setFrult] = useState("");
return (
<div>
과일 : {" "}
<input
// input에 들어오는 값으로 {}안에 fruit를 넣고
value={fruit}
// onChange를 먹이면 event가 매개변수로서 딸려온다.
onChange={function (event) {
// 우리에게 유의미한 값은 "event.target.value" -> 외우자!
// 모르겠으면 console.log를 찍어보고 유의미한 값을 찾아야함
setFrult(event.target.value);
}}
/>
<br /> <br />
// input 태그 아래에 값이 바로 보일 수 있도록 {fruit} 넣어주기
{fruit}
</div>
);
}
export default App;
// 입력하는 대로 아래에 값이 똑같이 적혀 나온다.
import React, { useState } from "react";
function App() {
// 아이디와 비밀번호를 state로 관리하기 위해 아래와 같이 설정
const [id, setId] = useState("");
const [pw, setPw] = useState("");
// 아이디 필드가 변경될 경우의 이벤트 -> 함수가 길어지기 때문에 변수로 지정하여 사용
const onIdChangeHandler = (event) => {
// 가져오는 값은 우리에게 유의미한 값인 event.target.value 로 설정
setId(event.target.value);
};
// 비밀번호 필드가 변경될 경우의 이벤트
const onPwChangeHandler = (event) => {
setPw(event.target.value);
};
return (
<div>
<div>
// input value는 {id} 값으로 지정하고 onChange에 이벤트를 넣어준다.
아이디 : <input type='text' value={id} onChange={onIdChangeHandler} />
</div>
<div>
비밀번호 :{" "}
// 비밀번호는 보이면 안되기 때문에 type을 psaaword로 지정한다.
<input type='password' value={pw} onChange={onPwChangeHandler} />
</div>
<button
// 버튼에 onClick을 먹여준다.
onClick={function () {
alert(
// 안쪽에 입력 값이 들어가야하므로 백틱으로 적어주는 것이 편하다.
`고객님이 입력하신 아이디는 ${id}이며, 비밀번호는 ${pw}입니다.`
);
// alert 이후 setstate를 통해 빈 값으로 초기화 시켜준다.
setId('');
setPw('');
}}>
로그인
</button>
</div>
);
}
export default App;
메모리에 있는 값을 변경할 수 없는 것.
// 원시 데이터: 숫자, 문자, 불리언 등 -> 값을 바로 저장하여 변수가 바라보게 됨
let number = 1;
let secondNumber = 1;
console.log(number === secondNumber) // true가 나옴
// 원시 데이터가 아닌 것들: 객체, 배열, 함수 등
// -> 입력된 값과 변수의 주소 값이 따로 저장되고 변수는 주소 값을 바라보게 됨
let obj1 = {
name: 'kim',
}
// obj1과 같은 값이지만 입력된 값과 변수의 주소 값을 또 따로 저장하기 때문에 obj1과 obj2는 결과적으로는 다른 주소를 가지고 있기 때문에 서로 다르다는 결과 값이 나온다.
let obj2 = {
name: 'kim',
}
console.log(obj1 === obj2) // false가 나옴
// 원시 데이터: 숫자, 문자, 불리언 등 -> 값을 바로 저장하여 변수가 바라보게 됨
let number = 1;
let secondNumber = 1;
number = 2;
// 1이라는 값은 그대로 두고 2라는 값만 저장하여 number라는 변수가 2를 바라보게 됨
// secondNumber는 그대로 있는 1이라는 값을 그대로 바라보고 있음
// 메모리 주소가 변함 -> 원시데이터는 불변성이 있다.
// 원시 데이터가 아닌 것들: 객체, 배열, 함수 등
// -> 입력된 값과 변수의 주소 값이 따로 저장되고 변수는 주소 값을 바라보게 됨
let obj1 = {
name: 'kim',
}
obj1.name = 'park'
// 결과적으로 객체는 불변성이 없다.
// obj1의 name값은 바뀌었으나, obj1은 처음 주소 값을 그대로 바라보고 있음
let obj2 = {
name: 'kim',
}
※ 리액트는 화면을 렌더링할지를 state의 변화에 따라 결정한다.(단순 변수는 무시)
import React, { useState } from 'react'
function App() {
let count = 0;
const [input, setInput] = useState("");
return (
<div>
<input
value={input}
onChange={(event) => {
// setInput으로 re-rendering
setInput(event.target.value);
}}
/>
{input}
<button onClick={() => {
// 단순 변수는 무시
count++;
// console.log로는 값이 올라가는 것을 알 수 있다.
console.log(`count는 ${count}입니다.`);
}}>증가</button>
{count}
</div>
)
}
export default App
import React, { useState } from 'react'
function App() {
// count도 useState로 관리
const [count, setCount] = useState(0);
const [input, setInput] = useState("");
return (
<div>
<input
value={input}
onChange={(event) => {
setInput(event.target.value);
}}
/>
{input}
<br />
<button onClick={() => {
// 클릭했을 때 숫자가 하나씩 증가하도록 newCount 변수 지정
const newCount = count + 1;
// setCount로 newCount 변수 입력
setCount(newCount);
}}>증가</button>
{count}
</div>
)
}
export default App
import React, { useState } from "react";
function App() {
// 객체 state
const [obj, setObj] = useState({
name: "1habin",
age: 21,
});
return (
<div>
<div>{obj.name}</div>
<button onClick={() => {
// 클릭했을 때 아래의 이름으로 바꾸고 싶다.
obj.name = '2habin';
// console.log로는 name 값이 바뀌지만
console.log(obj)
// 보여지는 화면에서는 re-rendering이 되지 않음
setObj(obj)
}}>변경!</button>
</div>)
}
export default App;
import React, { useState } from "react";
function App() {
const [obj, setObj] = useState({
name: "1habin",
age: 21,
});
return (
<div>
<div>{obj.name}</div>
<button onClick={() => {
// 바뀔 이름을 먼저 선언을 해주고
obj.name = '2habin'
// ...(spread)를 사용하여 객체를 펼쳤다가 다시 모아 새로운 객체를 만든다.
const obj2 = {...obj}
// 변경을 누르면 이름이 바뀌게 된다.
setObj(obj2)
}}>변경!</button>
</div>)
}
export default App;
처음에 강의를 따라서 코드를 적다가 console.log에 찍히는 값과 rendering되어 화면에 보이는 값이 달라서 당황했었다. 강의를 들을 때는 내용이 이해가 되다가도 백지에서 다시 코드를 작성하려고 보니 내 머릿속도 하얗게.. 되었다.. 곧 리액트 심화과정으로 넘어가는데, 리액트 강의는 자바스크립트 강의보다 더 많이 봐야할 것 같다😂