[새싹(SeSAC) 프론트엔드] day31 221128
자바스크립트의 배열
- 다양한 자료형을 저장 가능
// 숫자형
const numberList = [1, 2, 3, 4, 5]
//2개 이상의 자료형
const mixedList = [1, 'str', {}, function a() {} ];
XML과 JSX또한 저장 가능
// JSX 배열
const componentList = [<Mycomponent />, ... ]
📍state
- 값을 저장하거나 변경할 수 있는 객체
- 컴포넌트 내부에서 바뀔 수 있는 값을 의미
- 주로 버튼 클릭과 같은 이벤트와 함께 사용
1. 함수형 컴포넌트의 useState 함수
2. 클래스형 컴포넌트의 state 속성
props | state |
부모 컴포넌트가 설정한 값을 전달받아 읽기 전용으로만 사용 가능 | |
컴포넌트 내부에서 값을 직접 변경할 수 없음 | 값을 변경할 수 있음 |
ex. 장바구니 수량 추가, 댓글 남기기 |
(*) props의 값에 새로운 값을 대입해줘도 정말 값이 바뀌지 않을까?
app.js
function App() {
return (
<>
<ChangePropsValue name="yul" />
</>
);
}
ChangePropsValue.jsx
const ChangePropsValue = (props) => {
let { name } = props;
console.log(name);
name = props.name;
console.log(name);
function changeName() {
console.log("변경전 : " + name);
name = "React";
console.log("변경후 : " + name);
}
return (
<div>
<div>사용자의 이름은 {name}입니다</div>
<button onClick={changeName}>클릭</button>
</div>
);
};
- 내부적으로 name 값이 변경되었지만 바뀐 값이 반영되진 않음
- 변수의 값이 변경되었다고 리렌더링 되지는 않음
: 함수 자체 내부에서만 변경이 되었다고 컴포넌트의 렌더링이 다시 이루어지진 않음
➡️ function ChangePropsValue()함수가 다시 실행되도 처음부터 다시 props값을 받아오기 때문에 어차피 똑같은 결과가 됨
📍함수형 컴포넌트의 useState
const [value, setValue] = useState(초기값);
//value : 현재 상태(값)
// setValue : 상태를 바꾸어 주는 함수
** ❗️❗️❗️초기값의 형태 : 숫자, 문자열, 객체, 배열❗️❗️❗️
//초기값은 ('') 이런식으로 빈 값을 넣어줘도 됨
(*) useState를 활용하여 출력하기
Hello.jsx
const Hello = () => {
const [sayHi, setSayHi] = useState("안녕하세요");
const [sayHellos, setSayHellos] = useState([
"안녕하세요 ",
"반가워요 ",
"잘가요 ",
]);
const [font, setFont] = useState("30px");
const fstyle = { fontSize: font };
return (
<div>
<h3>{sayHi}</h3>
<hr />
<h3 style={fstyle}>{sayHellos}</h3>
<h3>{sayHellos[0]}</h3>
<h3>{sayHellos[1]}</h3>
<h3>{sayHellos[2]}</h3>
</div>
);
};
App.js
function App() {
return (
<>
<Hello />
</>
);
}
*useState 는 한 문서안에서 여러번 원하는 값을 가지고 만들 수 있음
객체 또는 배열의 state값 변경하기
➡️ 객체 또는 배열의 복사본을 만들어 값을 업데이트 한 후, 복사본의 상태를 useState()함수를 통해 업데이트
객체 또는 배열의 복사본 만들기
- spread 연산자(...) 사용
//객체를 spread연산자를 이용해 복사를 하면서 값 수정도 가능)
const object = { a : 1 , b : 2, c : 3 };
//object 객체의 사본 저장 후, b값만 변경
const copyObject= {...object, b:50 };
console.log(copyObject); // { a : 1, b : 50, c : 3}
(*) 실습
Spread.jsx
const Spread = () => {
const person1 = { name: "yul" };
const person2 = { name: "yul", age: 20 };
const person3 = { name: "yul", age: 20, region: "seoul" };
const test1 = { name: "yul" };
// const test2 = test1;
// test2.age = 20;
const test2 = { ...test1, age: 20 };
// const test3 = test2;
// test3.region = "busan";
const test3 = { ...test2, region: "busan" };
const test4 = { ...test3, region: "paju" };
//순서가 중요함! 뒤에 값이 앞의 값을 갱신하므로 바꿨다가 다시 원래대로 돌아간 형태가 됨
const test5 = {region:"pau", ...test3}
return (
<div>
<div>
<h4>person1 : {JSON.stringify(person1)}</h4>
<h4>person2 : {JSON.stringify(person2)}</h4>
<h4>person3 : {JSON.stringify(person3)}</h4>
</div>
<br />
<hr />
<br />
<div>
<h4>test1 : {JSON.stringify(test1)}</h4>
<h4>test2 : {JSON.stringify(test2)}</h4>
<h4>test3 : {JSON.stringify(test3)}</h4>
<h4>test4 : {JSON.stringify(test4)}</h4>
<h4>test5 : {JSON.stringify(test5)}</h4>
</div>
</div>
);
};
(*)Spread와 useState 같이 사용하기
Spread.jsx
const SpreadArr = () => {
const [value, setValue] = useState(["hi", "hello"]);
function changeArr() {
//spread를 이용하여 복사
let cValue = [...value];
cValue[1] = "안녕하세요";
setValue(cValue);
}
return (
<div>
<h1>{value[0]}</h1>
<h1>{value[1]}</h1>
<button onClick={changeArr}>값 변경</button>
</div>
);
};
📍클래스형 컴포넌트의 state 속성
생성자로 this.state를 초기화해주는 과정이 반드시 필요함
함수건 클래스건
"등호연산자로 값을 변경"이 "화면 갱신"을 의미하지 않는다
값 변경 경
값 변수 = 변경할 값 | 값 변경 ⭕️ 화면 갱신 ❌ |
값변경함수(변경할 값) | 값 변경 ⭕️ 화면 갱신 ⭕️ |
useState -> 리액트 엔진 -> 개발자가 값 변경을 원해요
리엑트 엔진
-> 컴포넌트 방문
->Jsx return ()
->변경사항 체크
->실제 변경된 부분만 갱신
->변경 안된 부분은 유지
📍state 끌어올리기 (Lifting State Up)
자식 component끼리는 값을 공유하지 못함
➡️ a자식이 부모에게 값을 넘겨준 뒤(Lifting state up)
➡️ b자식이 이걸 props를 통한 state로 전달받음
- 상위 컴포넌트의 '상태를 변경하는 함수(=setValue)' 그 자체를 하위 컴포넌트로 전달(props)
: 전달된 함수를 하위 컴포넌트가 실행
App.js
const [name , setName] = useState();
<ChildComponent1 name1 = setName />
<ChildComponent2 name2 = name />
ChildCom1.js
@ 값생성
props.setName
props.setName(보내고 싶은 값)
App.js
function App() {
//타입의 제약을 걸고 싶다면 props.type사용하기
const [value, setValue] = useState(0);
function addDataHandler(data) {
setValue(data);
}
return (
<>
<div>
<h3>ChildComponent로부터 전달받은 데이터 : {value}</h3>
<ChildComponent onAddData={addDataHandler} />
<ChildComponent2 value={value} />
</div>
</>
);
}
ChildComponent.jsx
const ChildComponent = (props) => {
function updateValue(e) {
props.onAddData(e.target.value);
}
return (
<div>
<h3>
입력 : <input type="text" onChange={updateValue} />
</h3>
</div>
);
};
ChildComponent2.jsx
const ChildComponent2 = (props) => {
let { value } = props;
return <div>state 끌어올리기를 통해 전달 받음 값 : {value} </div>;
};
새싹DT 기업연계형 프론트엔드 실무 프로젝트 과정 7주차 블로그 포스팅(월)