새싹 프론트엔드 실무 과정 7주차 React state
6. state
state
- 값을 저장하거나 변경할 수 있는 객체
- 컴포넌트 내부에서 바뀔 수 있는 값을 의미
- 주로 버튼 클릭과 같은 이벤트와 함께 사용함
- 읽기전용❌ 값이 계속 바껴야 함
props와 차이점
- props는 부모 컴포넌트가 설정한 값을 전달받아 읽기 전용으 로만 사용할 수 있음
➡ ChangePropsValue.js
import React from "react";
const ChangePropsValue = (props) => {
let name = props.name;
function changeName() {
name = "React";
}
return (
<div>
<h1>{props.name}</h1>
<button onClick={changeName}>클릭</button>
</div>
);
};
export default ChangePropsValue;
➡ App.js
import React from "react";
import ChangePropsValue from "./파일위치";
const App = () => {
return <div>
<ChangePropsValue name="gan"/>
</div>;
};
export default App;
➡ 부모가 "gan"을 보내고 있어서, 화면을 갱신해주지 않음
useState 함수
- 값의 형태 : 숫자, 문자열, 객체, 배열
- 리턴 값
배열
첫 번째 원소 : 현재 상태
두 번째 원소 : 상태를 바꾸어 주는 함수
➡ const [name, setName] = useState(값); 으로 변경 가능
➡ Hello.js
import { useState } from "react";
const Hello = () => {
const [인사, 인사변경] = useState('안녕하세요')
return (
<div>
<h3>{인사}</h3>
</div>
);
};
export default Hello;
➡ App.js
import React from "react";
import Hello from "./2022-11-28/Hello";
const App = () => {
return (
<div>
<Hello />
</div>
);
};
export default App;
➡ Hello.js
import { useState } from "react";
const Hello = () => {
const [인사, 인사변경] = useState(['안녕하세요', '재미있는', '리액트'])
return (
<div>
<h3>{인사[0]}</h3>
<h3>{인사[1]}</h3>
<h3>{인사[2]}</h3>
</div>
);
};
export default Hello;
배열도 가능
➡ Hello.js
import { useState } from "react";
const Hello = () => {
const [value, setValue] = useState("안녕하세요");
function printConsole() {
console.log(value);
}
return (
<div>
<h1>{value}</h1>
<button onClick={printConsole}>클릭</button>
</div>
);
};
export default Hello;
➡ Hello.js
import { useState } from "react";
const Hello = () => {
const [value, setValue] = useState("안녕하세요");
function chageValue() {
setValue("반가워요");
}
return (
<div>
<h1>{value}</h1>
<button onClick={chageValue}>클릭</button>
</div>
);
};
export default Hello;
클릭을 하면 변함!
return 안에 있는 화면 출력 부분만 확인하면서, 실제 값이 변경된 부분만 체크!
state 값 변경
- 객체/배열에 대한 사본 만들기 : spread 연산자(...) 사용
➡ Spread.js
import React from "react";
const Spread = () => {
const person1 = { name: "gan" };
const person2 = { name: "gan", age: 20 };
const person3 = { name: "gan", age: 20, region: "seoul" };
return (
<div>
<h1>{JSON.stringify(person1)}</h1>
<h1>{JSON.stringify(person2)}</h1>
<h1>{JSON.stringify(person3)}</h1>
</div>
);
};
export default Spread;
➡ Spread.js
import React from "react";
const Spread = () => {
const person1 = { name: "gan" };
// const person2 = { name: "gan", age: 20 };
// const person3 = { name: "gan", age: 20, region: "seoul" };
const person2 = person1;
person2.age = 20;
const person3 = person2;
person3.region = "seoul";
return (
<div>
<h1>{JSON.stringify(person1)}</h1>
<h1>{JSON.stringify(person2)}</h1>
<h1>{JSON.stringify(person3)}</h1>
</div>
);
};
export default Spread;
➡ 하나의 공간을 공유해서 결과가 생각하는 것과 다르게 나옴!!
✅ 객체를 복사 할 때, 스프레드 연산자를 이용
import React from "react";
const Spread = () => {
const person1 = { name: "gan" };
const person2 = { ...person1, age: 20 };
const person3 = { ...person2, region: "seoul" };
return (
<div>
<h1>{JSON.stringify(person1)}</h1>
<h1>{JSON.stringify(person2)}</h1>
<h1>{JSON.stringify(person3)}</h1>
</div>
);
};
export default Spread;
import React from "react";
const Spread = () => {
const person1 = { name: "gan" };
const person2 = { ...person1, age: 20 };
const person3 = { ...person2, region: "seoul" };
const person4 = { ...person3, region: "Busan" };
return (
<div>
<h1>{JSON.stringify(person1)}</h1>
<h1>{JSON.stringify(person2)}</h1>
<h1>{JSON.stringify(person3)}</h1>
<h1>{JSON.stringify(person4)}</h1>
</div>
);
};
export default Spread;
➡ 서울이 부산으로 바뀜
const person4 = { region: "Busan", ...person3 };
부산이 아닌 서울로 나옴! 순서가 중요!
➡ ChangeArray.js
import React from "react";
import { useState } from "react";
const ChangeArray = () => {
const [value, setValue] = useState(["안녕", "하이"]);
function changeArr() {
var cValue = [...value];
cValue[1] = "Hello";
setValue(cValue);
}
return (
<div>
<h1>{value[0]}</h1>
<h1>{value[1]}</h1>
<button onClick={changeArr}>배열 값 변경</button>
</div>
);
};
export default ChangeArray;
➡ setValue(cValue); 해줘야지만 화면 변경이 됨!
< 어떤 변수의 값을 변경하려면 >
1. const [값변수, 값변경 함수] = useState(초기값)
2. 값 변경 ⭐⭐
- 값변수 = 변경할 값 ➡ 값 변경⭕, but 화면 갱신❌
- 값 변경 함수(변경할 값) ➡ 값 변경⭕, 화면 갱신⭕
3. 값 변경 작동 원리
- useState -> 리액트 엔진 -> 개발자가 값 변경을 원해요
- 리액트 엔진 -> 컴포넌트 방문 -> JSX 문법이 작성되어 있는 return() 을 확인 ->
변경사항 체크 -> 실제 변경된 부분만 갱신 (변경 안된 부분은 유지)
➡ 생성자 안에서 초기화
state 끌어올리기
➡ 형제 컴포넌트 간 데이터 공유 ❌
➡ 가장 가까운 공통 부모에게 state를 끌어올려 공유
➡ props를 통한 state 전달
- 부모는 자식한테 자신이 가진 데이터(문자열, 숫자, 배열, 객체, 함수) 전달 가능
const [value, setvalue] = useState(0)
자식1한테 함수를 전달 => setValue()
자식1
-> 데이터를 생성 : 10
-> props -> setValue(값) -> props.setValue(10)
부모가 가진 10을 자식 2에게 전달
<ChildCom2 num={value}/>
➡ App.js
import React, {useState} from "react";
import ChildComponent from "./파일위치";
const App = () => {
const [value, setValue] = useState(' ');
function addDataHandler(data) {
setValue(data);
}
return (
<div>
<h3>ChildComponent로 부터 전달받은 데이터 : {value} </h3>
<ChildComponent onAddData = {addDataHandler}/>
</div>
);
};
export default App;
➡ ChildComponent.js
import React from "react";
const ChildComponent = (props) => {
function updateValue(e) {
props.onAddData(e.target.value);
}
return (
<div>
<h3>
입력 : <input type="text" onChange={updateValue} />
</h3>
</div>
);
};
export default ChildComponent;
콘솔로 찍어 봤을 때,
console.log(e.target); ➡ 타입
console.log(e.target.value); ➡ 입력 값
콘솔로 확인해보기!
새싹DT 기업연계형 프론트엔드 실무 프로젝트 과정 7주차 블로그 포스팅