-최초로 컴포넌트가 실행되는 것
-컴포넌트가 제거되는 것
1.constructor(생성자)
-컴포넌트가 실행될 때 제일 먼저 호출된다.
-this.state
를 이용해 state를 초기화한다.
2.render
-화면에 그려진다.
-props
나 state
변화가 있을 때마다 호출된다.
-부모 컴포넌트에 자식 컴포넌트가 있을 경우 부모 컴포넌트 렌더 후 자식 컴포넌트가 렌더된다.
3.componentDidMount
-최초 render()
후 한 번만
호출된다.
-render()
가 된 상태(화면에 레이아웃이 보여지는 상태)에서 외부에서 데이터를 가져올 때 사용한다.
그 데이터를 this.setState
를 사용해 state
에 저장한다.
ex) data loading (api 호출)
4.render
-state
가 변경된 상태
5.이벤트 발생 시 이벤트 함수 호출 후 render
-자식 컴포넌트에 함수를 props
로 전달하면 자식 컴포넌트에서 이벤트가 발생 후 이벤트 함수가 호출되고 부모 컴포넌트 렌더 후 자식 컴포넌트가 렌더된다.
6.componentDidUpdate
-state가 변화한 후 호출된다.
componentWillUnmount
-컴포넌트가 제거될 때 호출된다.
App.js
class App extends Component { state = { monsters: [], userInput: "" }; componentDidMount(){ fetch("https://jsonplaceholder.typicode.com/users") .then((response)=>response.json()) .then((response)=>this.setState({monsters : response})); } handleChange = (e) => { this.setState({userInput : e.target.value}) } render() { const user = this.state.monsters.filter((monster)=>{ return monster.name.toLowerCase() === this.state.userInput }) return ( <div className="App"> <h1>컴포넌트 재사용 연습!</h1> <SearchBox handleChange={this.handleChange} /> <CardList monsters={user}/> </div> ); } } export default App;
state가 초기화된다. (monsters : [],userInput : ""
)
<App />
의 render()
호출 후 DOM에 return의 요소가 추가된다.
componentDidMount()
가 호출되고 fetch
를 통해 users의 데이터를 요청하고 응답받은 데이터를 this.setState
후 render()
가 호출된다.
SearchBox.js
class SearchBox extends Component { render() { return ( <input className="search" type="search" placeholder="Search..." onChange={this.props.handleChange} /> ); } } export default SearchBox;
4.<SearchBox />
(자식)에 이벤트 함수 handleChange
를 props
로 전달해 이벤트가 발생하면 userInput
값이 바뀌고 <App />(부모)의 render()
호출 후 <SearchBox />(자식)의 render()
가 호출된다.
CardList.js
class CardList extends Component { render() { return ( <div className="card-list"> {this.props.monsters.map((monster,i)=>{ return ( <Card key={i} name={monster.name} email={monster.email} id={monster.id}/> )})} </div> ) } } export default CardList;
Card.js
class Card extends Component { render() { return ( <div className="card-container"> <img src={`https://robohash.org/${this.props.id}?set=set2&size=180x180`} alt="" /> <h2>{this.props.name}</h2> <p>{this.props.email}</p> </div> ); } } export default Card;
render()
가 발생하면 소문자 monster.name
과 userInput
이 같을 때 filter
한 결과를 <CardList />
(자식)에 props
로 전달한다.
전달받은 monsters
배열을 map
을 사용해 <Card />
(<CardList />
의 자식)에 name, email, id를 props
로 전달하고 <Card />
의 render()
를 호출한다.
-map
사용 시 return 요소로 컴포넌트를 사용하면 그 컴포넌트는 고유한 값을 가져야한다. 이 값을 key
로 부여한다.
-복제된 컴포넌트들이 각자 고유한 값을 가져야 그 고유값을 이용해 어느 것이 변화했는지 알아낼 수 있다.
-편의상 map
의 두번째 매개변수로 오는 index
를 key
로 사용한다. index
를 key
로 사용할 경우 배열의 요소가 추가, 변경되었을 때 key
값도 계속 변화하기 때문에 컴포넌트의 state와 관련된 문제가 발생할 수 있다. 따라서 고유한 값(ex) email)을 key
로 사용하는 것이 좋다.