state 관리
단방향 데이터 흐름?
데이터는 위에서 아래로, 부모에서 자식으로 넘겨줘야함
why 단방향?
부모컴포넌트의 state가 업데이트가 되면서 자식 컴포넌트도 리렌더링이 일어남
생성-> 수정->삭제
수정이 되는경우가 4가지였는데
-> 컴포넌트자체 state가 바뀔때
-> 내 props가 바뀌는 경우
-> 부모가 리렌더링 되는 경우(부모의 무언가가 바뀌는경우)
-> 강제 업데이트
부모의 state가 있다면 그것을 자식한테 그대로 넘겨준다라고 생각할때
자식한테는 그것이 props임
여기까지 생각할때 부모의 state가 변함 -> 그럼 부모는 리렌더링이됨
부모가 리렌더링되었으니까 혹은 props가 바뀌었으니까 자식이 다시 렌더링되는건 여기에서 작업이 끝남
자식이 부모한테 데이터를 주는 상황에 만약 자식의 부모의 props나 state라든가 무언가에 영향을 준다라고 생각하면
자식이 부모의 렌더링을 일으킴. 부모가 재렌더링되니까 자식도 당연히 재렌더링을 함
이렇게 하다보면 무한루프에 빠져버림.
무조건은 아님, 부모의 props나 state를 자식한테 안내려보내주는 경우도 있음. 자식이 부모에게 다시 state나 props변하게 하게끔
유발하는 행동이 없을수도 있다는 뜻.
그래서 양방향보다는 단방향이 좋음.
//클래스형 컴포넌트에서 state관리하는 방법
import React from "react";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
//이 숫자를 가지고 배열을 만들고 배열을 만든 후 배열만큼 map돌려주면됨
count: 3,
};
}
//이 state를 콘솔에서 조금 확인하고 싶기때문에
componentDidMount() {
//console.log(this.state)
}
render() {
//배열만들기(배열의 길이로 가져오면 되는데, length가 key가 되고 숫자가 값, 그리고 새로 만든 이 배열에 요소 하나하나 인덱스 값을 넣어줌)
const nemo_count = Array.from({ length: this.state.count }, (v, i) => i);
return (
<div className="App">
<div
style={{
width: "150px",
height: "150px",
backgroundColor: "#ddd",
margin: "10px",
}}
>
nemo
</div>
</div>
);
}
}
export default App;
이제 네모가 만들어지고 array가 잘 출력되는 것을 확인하였으면
이제 App className밑에 양식인 네모 div를 뿌려주면 됨
import React from "react";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
//이 숫자를 가지고 배열을 만들고 배열을 만든 후 배열만큼 map돌려주면됨
count: 3,
};
}
//이 state를 콘솔에서 조금 확인하고 싶기때문에
componentDidMount() {
//console.log(this.state)
}
render() {
//배열만들기(배열의 길이로 가져오면 되는데, length가 key가 되고 숫자가 값, 그리고 새로 만든 이 배열에 요소 하나하나 인덱스 값을 넣어줌)
const nemo_count = Array.from({ length: this.state.count }, (v, i) => i);
return (
<div className="App">
{nemo_count.map(() => {
return (
<div
style={{
width: "150px",
height: "150px",
backgroundColor: "#ddd",
margin: "10px",
}}
>
nemo
</div>
);
})}
비교하기 위한 값 -> key, 이런 key는 자동으로 들어감(Elements 탭에서는 확인할수 없음, 실제 DOM에 들어가는 속성은 아니기 때문)
map으로 만들게되면(이거는 함수인데) return을 하게 되면 이 함수가 또 돌게됨 요소들을 또 만들게 됨
첫번째로 만들어진 요소랑 두번째로 만들어진 요소는 key 값이 다름(왜냐하면 매번 다른 랜덤 키가 생성되니까, 비교를 하는 의미가없음)
그래서 map을 돌리고 나면 warning이 뜸, 리스트 안에 있는 각각 요소들은 꼭 유니크한 키값을 너가 넘겨줘야한다라고
(무시해도 상관은 없지만 경고문 안뜨게 하려면 그리고 렌더링에 유리하게 할려면
map은 nemo_count.map((n, i) =>
하면 n에는 각각의 요소가, i에는 각각의 index가 들어가는데
render() {
//배열만들기(배열의 길이로 가져오면 되는데, length가 key가 되고 숫자가 값, 그리고 새로 만든 이 배열에 요소 하나하나 인덱스 값을 넣어줌)
const nemo_count = Array.from({ length: this.state.count }, (v, i) => i);
return (
<div className="App">
{nemo_count.map((n, i) => { //이렇게 map에 임의지정을 해버리면 warning이 뜨지않음
return (
<div
key={i} //key는 index값으로 for loop돌면서 줘버림(return)
style={{
width: "150px",
height: "150px",
backgroundColor: "#ddd",
margin: "10px",
}}
>
nemo
</div>
);
})}
</div>
);
}
}
</div>
);
}
}
export default App;
버튼을 만들었으면 이제 눌렀을때 작동하는 함수 만들기
//첫번째 방법
import React from "react";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
//이 숫자를 가지고 배열을 만들고 배열을 만든 후 배열만큼 map돌려주면됨
count: 3,
};
}
//이 state를 콘솔에서 조금 확인하고 싶기때문에
componentDidMount() {}
//네모하나 추가
addNemo = () => {
//setState()은 위에 있는 this.state을 바꿔주는것임, 딕셔너리 형태이니 {}를 안에넣기
this.setState({ count: this.state.count + 1 });
};
render() {
//배열만들기(배열의 길이로 가져오면 되는데, length가 key가 되고 숫자가 값, 그리고 새로 만든 이 배열에 요소 하나하나 인덱스 값을 넣어줌)
const nemo_count = Array.from({ length: this.state.count }, (v, i) => i);
return (
<div className="App">
{nemo_count.map((n, i) => {
return (
<div
key={i}
style={{
width: "150px",
height: "150px",
backgroundColor: "#ddd",
margin: "10px",
}}
>
nemo
</div>
);
})}
<div>
<button onClick={() => {
this.addNemo();
}}>하나 추가</button>
<button>하나 빼기</button>
</div>
</div>
);
}
}
export default App;
두번째 방법
import React from "react";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
//이 숫자를 가지고 배열을 만들고 배열을 만든 후 배열만큼 map돌려주면됨
count: 3,
};
}
//이 state를 콘솔에서 조금 확인하고 싶기때문에
componentDidMount() {}
//네모하나 추가
addNemo = () => {
//setState()은 위에 있는 this.state을 바꿔주는것임, 딕셔너리 형태이니 {}를 안에넣기
this.setState({ count: this.state.count + 1 });
};
render() {
//배열만들기(배열의 길이로 가져오면 되는데, length가 key가 되고 숫자가 값, 그리고 새로 만든 이 배열에 요소 하나하나 인덱스 값을 넣어줌)
const nemo_count = Array.from({ length: this.state.count }, (v, i) => i);
return (
<div className="App">
{nemo_count.map((n, i) => {
return (
<div
key={i}
style={{
width: "150px",
height: "150px",
backgroundColor: "#ddd",
margin: "10px",
}}
>
nemo
</div>
);
})}
<div>
<button onClick={this.addNemo}>하나 추가</button>
<button>하나 빼기</button>
</div>
</div>
);
}
}
export default App;
근데 이렇게 할거면 소괄호 addNemo()이렇게 하면안됨 그렇게하면 즉시실행이됨
즉 클릭도 안했는데 뭔가 state가 자꾸 올라가버리게됨.
마지막으로 removeNemo()함수 만들어서 지워주는 함수 만들어주고 0이 될때 -1,-2 이렇게 array가 만들어지면 안되니 if조건문 달아주고 <div>가 0이 될때 더 지워주려는 함수를 사용할때는 alert가 나게 만들었다.
import React from "react";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
//이 숫자를 가지고 배열을 만들고 배열을 만든 후 배열만큼 map돌려주면됨
count: 3,
};
}
//이 state를 콘솔에서 조금 확인하고 싶기때문에
componentDidMount() {}
//네모하나 추가
addNemo = () => {
//setState()은 위에 있는 this.state을 바꿔주는것임, 딕셔너리 형태이니 {}를 안에넣기
this.setState({ count: this.state.count + 1 });
};
removeNemo = () => {
if (this.state.count > 0) {
this.setState({ count: this.state.count - 1 });
} else {
window.alert("네모가없어요!");
}
};
render() {
//배열만들기(배열의 길이로 가져오면 되는데, length가 key가 되고 숫자가 값, 그리고 새로 만든 이 배열에 요소 하나하나 인덱스 값을 넣어줌)
const nemo_count = Array.from({ length: this.state.count }, (v, i) => i);
console.log(this.state);
return (
<div className="App">
{nemo_count.map((n, i) => {
return (
<div
key={i}
style={{
width: "150px",
height: "150px",
backgroundColor: "#ddd",
margin: "10px",
}}
>
nemo
</div>
);
})}
<div>
<button onClick={this.addNemo}>하나 추가</button>
<button onClick={this.removeNemo}>하나 빼기</button>
</div>
</div>
);
}
}
export default App;
'리액트(React)' 카테고리의 다른 글
리액트에서 Ref를 활용한 DOM 요소 가져오기 (0) | 2022.07.25 |
---|---|
리액트에서 함수 component를 사용하여 state다루기(div추가/div삭제) 훅(Hook) (0) | 2022.07.25 |
클래스형 component와 함수형 component (0) | 2022.07.24 |
양방향 바인딩(2way data binding)이란 무엇인가? (0) | 2022.07.22 |
리액트안에서의 자바스크립트 (0) | 2022.07.21 |