1) 단방향 데이터 흐름이란?
: 데이터는 위에서 아래로, 부모에서 자식으로 넘겨줘야 한다는 소리입니다.
+ 왜 단방향을 써야 하나요??
: 라이프 사이클과 함께 생각해보기 부모 컴포넌트의 state가 업데이트 되면 자식 컴포넌트도 리렌더링이 일어납니다.
만약 자식 컴포넌트의 state가 바뀐 걸 부모 컴포넌트가 props로 받는다고 생각해봅시다.
그러면 자식 컴포넌트가 업데이트 될 때 부모 컴포넌트도 업데이트 되겠죠?
앗..., 그럼 또 자식 컴포넌트가 리렌더링 될 거구요.
무한반복 렌더링이 일어나게 됩니다.!!
2) 클래스형 컴포넌트에서 state 관리 - setState()
: 라이프 사이클을 볼 때 잠깐 봤던 setState()!
클래스형 컴포넌트의 state를 업데이트할 때 사용하는 함수입니다.
import React from "react";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 3, // 숫자넣기!
};
}
componentDidMount() { }
addNemo = () => {
// this.setState로 count를 하나 더해줍니다!
this.setState({ count: this.state.count + 1 });
};
removeNemo = () => {
// 네모 갯수가 0보다 작을 순 없겠죠! if문으로 조건을 걸어줍시다.
if (this.state.count > 0) {
// this.setState로 count를 하나 빼줍니다!
this.setState({ count: this.state.count - 1 });
} else {
window.alert('네모가 없어요!');
}
};
render() {
// 배열을 만듭니다.
// Array.from()은 배열을 만들고 초기화까지 해주는 내장 함수입니다.
// Array.from()의 첫번째 파라미터로 {length: 원하는 길이} 객체를,
// 두번째 파라미터로 원하는 값을 반환하는 콜백함수를 넘겨주면 끝!
// array의 내장함수 대부분은 콜백 함수에서 (현재값, index넘버)를 인자로 씁니다.
const nemo_count = Array.from({ length: this.state.count }, (v, i) => i);
// 콘솔로 만들어진 배열을 확인해봅니다. 숫자가 0부터 순서대로 잘 들어갔나요?
console.log(nemo_count);
return (
<div className="App">
{nemo_count.map((num, idx) => {
return (
<div
key={idx}
style={{
width: "150px",
height: "150px",
backgroundColor: "#ddd",
margin: "10px",
}}
>
nemo
</div>
);
})}
<div>
{/* 함수를 호출합니다. 이 클래스 안의 addNemo 함수를 불러오기 때문에 this.addNemo로 표기해요. */}
<button onClick={this.addNemo}>하나 추가</button>
<button onClick={this.removeNemo}>하나 빼기</button>
</div>
</div>
);
}
}
export default App;
3) 함수형 컴포넌트에서 state 관리 - useState()
: 이번에는 함수형 컴포넌트에서 어떻게 state를 쓸 수 있는 지 봅시다.
함수형 컴포넌트는 클래스형처럼 자체적으로 state를 가지고 있지 않지만, react hooks를 사용하면 state를 가질 수 있습니다!
특히 컴포넌트를 만들고→ state를 쓰는 순서! 뷰 먼저→ 그 다음은 state를 만들고(기본값도 잡아주고!)→ state를 조작하는 무언가를 만들어서→연결한다! 이 순서가 중요해요!
import React from 'react';
function Nemo(props) {
const [count, setCount] = React.useState(3)
const nemo_count = Array.from({ length: count }, (v, i) => i);
const addNemo = ()=>{
setCount(count + 1);
}
const removeNemo = ()=>{
if(count > 0){
setCount(count - 1);
}else{
alert("네모가 없어요!!")
}
}
return (
<>
{
nemo_count.map((num, idx) => {
return (
<div
key={idx}
style={{
width: "150px",
height: "150px",
backgroundColor: "#ddd",
margin: "10px",
}}
>
nemo
</div>
);
})
}
< div >
{/* 함수를 호출합니다. 이 클래스 안의 addNemo 함수를 불러오기 때문에 this.addNemo로 표기해요. */ }
<button onClick={addNemo}> 하나 추가</button >
<button onClick={removeNemo}>하나 빼기</button>
</div >
</>
);
}
export default Nemo;
퀴즈 - 버킷리스트에 아이템을 추가 해보자!
👻 힌트:
- 뷰를 먼저 만들어주세요! 텍스트를 입력할 공간과 [추가하기] 버튼을 잊지말고 추가하기!
- ref! 잊지 않았죠? text를 가져올 때 써줍니다.
- 인풋박스에 입력한 값은 [인풋박스 ref].current.value로 가져올 수 있습니다.
- 버킷리스트 컴포넌트는 만질 필요가 없어요. (소근)
-> App.js
import React from "react";
import BucketList from "./BucketList";
import styled from "styled-components";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
list: ["영화관 가기", "매일 책읽기", "수영 배우기"],
};
this.text = React.createRef();
}
componentDidMount() {
}
addBucket = () => {
console.log(this.text.current.value);
const new_item = this.text.current.value;
// ... => 스프레드 문법
// [...this.state.list, 넣고 싶었던 어떤 값]
this.setState({ list: [...this.state.list, new_item] });
}
render() {
return (
<AppWrap className="App">
<Container>
<Title>내 버킷리스트</Title>
<Line />
<BucketList list={this.state.list} />
</Container>
<InputWrap>
<input type="text" ref={this.text} />
<button onClick={this.addBucket}>추가하기</button>
</InputWrap>
</AppWrap>
);
}
}
const AppWrap = styled.div`
background-color: #eee;
height: 100vh;
width: 100vw;
display: flex;
flex-direction: column;
`;
const Container = styled.div`
background-color: #fff;
width: 50vw;
max-width: 350px;
margin: auto;
height: 80vh;
padding: 16px;
border: 1px solid #ddd;
border-radius: 5px;
`;
const Title = styled.h1`
color: slateblue;
text-align: center;
`;
const Line = styled.hr`
margin: 16px 0px;
`;
const InputWrap = styled.div`
background-color: #fff;
width: 50vw;
max-width: 350px;
margin: auto;
padding: 16px;
border: 1px solid #ddd;
border-radius: 5px;
`;
export default App;
-> BucketList.js
import React from "react";
import styled from "styled-components";
const BucketList = ({ list }) => {
const my_lists = list;
const my_wrap = React.useRef(null);
return (
<div ref={my_wrap}>
{my_lists.map((list, index) => {
return <ItemStyle key={index}>{list}</ItemStyle>;
})}
</div>
);
};
const ItemStyle = styled.div`
padding: 16px;
margin: 8px;
background-color: aliceblue;
`;
export default BucketList;
'항해 중 > 3주차 리액트 기초반' 카테고리의 다른 글
3주차 - Event Listener (0) | 2021.11.16 |
---|---|
2주차 - 숙제 (0) | 2021.11.15 |
2주차 - Ref(리액트에서 돔요소를 가져오는 방법) (0) | 2021.11.15 |
2주차 - CSS (0) | 2021.11.15 |
2주차 - Component (2) | 2021.11.15 |
댓글