map
- component 를 여러 개 만들기 위해서 map 을 쓸 때 그냥 map 을 돌리면 component 가 복제된다. 복제가 되었을 때에는 각 component 에서 변경사항이 있을 때 어떤 component 에서 변경사항이 생겼는지 파악이 어렵다. 이를 해결하기 위해서는 key 를 만들어주면 된다.
- key 의 값으로는 unique 한 값이 들어가야 한다. key 는 따로 사용되지는 않고 '컴포넌트에서 변화가 일어나면 key 로 해당 컴포넌트를 구별하라' 는 표시이다. key 값으로는 이메일 등을 준다.
key={user.email}
- 아래처럼 index 를 key 로 할 수도 있다. 하지만 정말 정말 유니크한 값이 없을 경우 최후의 수단으로 index 를 쓰는 것을 권장한다. 왜 최후의 수단이냐? -> 들어오는 데이터가 바뀔 경우 예를 들어서 들어오는 배열 객체가 10개 였다가 5개로 줄었을 때 map 을 다시 돌리면 리액트에서는 업데이트가 됐다고 생각을 안한다. 인덱스가 같기 때문에! 그렇기 때문에 데이터가 안 바뀐다.
- key 는 return 문 안의 최상위 태그에 적어줘야 한다.
setState, 동기, 비동기
- class 안의 constructor 랑 render 는 모두 함수이다. render 가 리턴하는 것은 jsx 문법으로 쓰여진 코드이다.
- constructor 에서는 class 안에서 쓸 변수의 초기값을 설정해준다. 안에서 만들어서 설정할 수도 있고 밖에서 받아서 설정할 수도 있다.
- contructor 는 생략할 수 있지만 쓰려면 무조건
super();
를 해줘야 한다. 그 후에 state 를 초기화 해준다. state 는 컴포넌트의 상태를 나타내는 객체이다. 컴포넌트 안 return 문 안에서 바뀌어야 할 부분이 있으면 그 데이터를 this.state 안에 저장해두고 동적으로 바꾸는 것이다.
- 실제 사이트가 배포가 되면 코드를 직접 건들일 수 없다. 따라서 배포 후에 state 값을 동적으로 바꿔야 할 일이 있으면 setState 로 바꿔준다.
- component 안에서 함수를 만들 때! 무조건 arrow function 으로 만들어라. 함수의 레퍼런스란 함수의 이름이라고 생각하면 된다.
- setState 안에 코드를 적어줄 때는 이렇게 생각하면 편하다. this.state 안에 있는 값을 똑같이 적어주고 값만 바꿔준다고 생각! 덮어쓴다고 생각하면 안된다. 실제로 기존 this.state 값과 setState 로 적어준 값은 다른 객체이다.
- 그때 그때 바뀌는 값을 저장해주는 곳이 state
- 이벤트를 만들어주고 나면 무조건 console.log 부터 찍어봐라. 디버깅 할 때 편하다.
- 함수를 확인하기 위해서 console.log 를 아래처럼 적어주면 안된다.
- 자바스크립트의 특징인 '비동기' 때문이다.
- 동기는 코드를 실행완료하고 다음 코드로 넘어간다.
- 비동기는 하나의 요청이라고 생각하자. 요청을 처리하지 않아도 다음 코드로 넘어간다.
- setState 는 비동기 요청이다. 따라서 e.target.value 를 userInput 에 넣지 않았는데 this.state.userInput 값을 출력한다. 그럼 입력한 값이 콘솔창에 하나씩 적게 출력된다.
- 비동기 문제를 피해서 console.log 를 찍어보려면 render 함수 밑에서 console.log 를 해준다. 왜냐면! render 함수는 무조건 컴포넌트에 변화가 있는 후!!!에야 호출이 되기 때문이다.
- 라이프사이클: constructor -> render -> 함수 -> render -> ...
componentDidMount
- CDM 은 최초 렌더 후에 딱 한 번만 호출된다. 이 특징을 이용해서 데이터를 로딩할 때 CDM 을 쓴다. 컴포넌트에 필요한 데이터를 서버에서 가져올 때 호출한다. product list 를 불러올 때 등! 꼭 CDM 에서만 서버 데이터를 받아와야 하는 건 아니지만 CDM 에서 하면 좋다.
- 그럼 constructor 도 한 번만 호출되는데 왜 CDM 에서만 데이터 받아오나? 그냥 컨벤션이다.
fetch
- 데이터 요청(비동기): fetch()
- 답변 (response) 확인: console.log()
- 내가 원하는 정보를 state 에 담는다: setState()
- render()
- fetch 함수는 위와 같이 써준다.
.then()
함수는 fetch 로 요청한 데이터의 응답이 왔을 때 어떻게 실행해 줄 함수이다. 이 함수는 arrow function 으로 적어준다. then 안에 적힌 response
는 response 타입이다.
- 응답은 response 의 body 안에 json 의 형태로 담겨있다. 따라서 response 를 자바스크립트 형태로 변환하는 .json 함수를 호출한다. 이것도 하나의 요청이기 때문에 응답이 온다. 이 응답을 console.log 에 찍어준다.
- json 은 하나의 프로토콜이다. 통신을 할 때 언어와 언어 사이의 번역기 역할을 한다고 생각하면 된다.
- 잘 들어온 데이터를 state 에 담아준다. state 에 users 라는 빈 배열을 생성한다.
- users 배열에 데이터를 담아주기 위해서 아래와 같이 작성한다.
componentDidMount() {
fetch("https://jsonplaceholder.typicode.com/users")
.then((res) => res.json())
.then((res) => this.setState({users: res}));
}
import React, { Component } from "react";
import "./StateProps.scss";
import StatePropsChild from "./StatePropsChild";
class StateProps extends Component {
constructor() {
super();
this.state = {
users: "",
};
}
componentDidMount() {
fetch("https://jsonplaceholder.typicode.com/users")
.then((res) => res.json())
.then((res) => this.setState({ users: res }));
}
sayHello = (e) => {
this.setState({ userInput: e.target.value });
console.log(this.state.userInput);
};
render() {
console.log("render: ", this.state.users);
return (
<div className="state">
<div className="state-header">State / Props 연습!!</div>
<div className="state-contents">
<input onChange={this.sayHello} type="text" />
</div>
</div>
);
}
}
export default StateProps;
진짜 눈높이 딱맞는 설명이네요 감사합니다 도움이많이되었습니다.