<aside> 💡 class없이 state를 사용할 수 있는 새로운 기능
</aside>
import React, { Component } from 'react'
import Axios from 'axios'
export default class Hello extends Component {
**constructor(props) {
super(props);
this.state = { name: " " };
} //1번째: 생성자 실행으로, state가 초기화된다.**
componentDidMount() {
Axios.get('/api/user/name')
.then(response => {
this.setState({ name: response.data.name })
}) // 서버에 요청을 보낸다. 실제 유저의 데이터를 가져온다음에 state에 넣어준다. state가 업데이트 되면 그때 컴포넌트가 다시 렌더링이 된다.
}
**render() {
return (
<div>
My name is {this.state.name}
</div>
)
} // 2번째: 초기화 할때 { name: " " } 빈 스트링을 사용했으므로 My name is 빈 스트링이 되고, 그 후 response.data.name에서 받아온 이름을 가지고 실제 이름이 들어간다.**
}
import React, { useEffect, useState } from 'react'
import Axios from 'axios'
export default function Hello() {
const [Name, setName] = useState("")
//useState를 이용해서 const [state, state를 이용하는 함수(관습적으로 set(state)를 사용한다.)] 로 구성한다.
useEffect(() => {
Axios.get('/api/user/name')
.then(response => {
setName(response.data.name)
})
}, []) //useEffect의 첫번쨰 매개변수로는 함수가, 두번째 매개변수로는 배열이 들어간다. 배열이 비어있으면, 컴포넌트가 마운트되고 함수를 한번만 호출한다. **그런데, 종속성배열 안에 [name]이 들어가 있으면, name이 바뀔 때마다 다시 호출된다.** 클래스형 컴포넌트에서는 componentDidUpdate문과 동일하다.
return (
<div>
My name is {Name}
</div>
)
}
##일반 클래스 컴포넌트
**componentDidMount() {
// 컴포넌트가 마운트 되면 updateLists 함수를 호출
this.updateLists (this.props.id)
}
componentDidUpdate (prevProps) {
if (prevProps.id !== this.props.id) {
//updatelists 함수를 호출할 때
// 사용되는 id가 달라지면 다시 호출
this.updateLists(this.props.id)
}
}**
//updateLists 함수 정의
updateLists = (id) => {
fetchLists(id)
.then((lists) => this.setState({
lists
}))
}
**## React Hooks를 이용한 생명주기를 이용
useEffect(()=> {
fetchLists(id)
.then((repos)=>{
setRepos(repos)
})
}, [id])**
화면에서 재사용가능한 로직만을 컴포넌트로 만든다.
유저정보를 가져와서 state에 넣어주었다.
export default class Apage extends Component {
state = {
user: []
}
**componentDidMount() {
fetchUsers()
.then(users => {
this.setState({ users })
}) // A페이지와 B페이지 모두 해당: 유저정보를 어딘가에서 가져와서 State에 넣어줬다. => 모든 컴포넌트에서 같은 로직을 작성하면 매우 비효율적!!**
}
render() {
const { users } = this.state;
return (
<div>
A 페이지
{users.map(({ name, url }) => (
<div key={name}>
<p>{name}, {url}</p>
</div>
))}
</div>
)
}
}
export default class Bpage extends Component {
state = {
user: []
}
**componentDidMount() {
fetchUsers()
.then(users => {
this.setState({ users })
})**
}
render() {
const { users } = this.state;
return (
<div>
B 페이지
{users.map(({ name, url }) => (
<div key={name}>
<p>{name}, {url}</p>
</div>
))}
</div>
)
}
}


return class usersHOC extends React.Component에서, HOC 클래스를 생성 후 userHOC 함수에서 return 해준다. componentDidMount() { … }에서 클래스 내에서 유저에 관한 작업(정보 받아오기)를 한 후 자녀 컴포넌트로 필요한 데이터를 내려준다.
오른쪽 사진에서, HOC 부모 컴포넌트에서 내려준 공통데이터를 사용할 수 있는데, Apage와 Bpage를 인자로 사용하여 왼쪽 state = { users: []} 에서 각각의 컴포넌트를 받아주고, component가 render 아래로 내려가므로, state를 props로 내려주면, 각각의 페이지에서 우측처럼 props로 유저정보를 가져온다. 실제로 중복되는 부분은 굉장히 많기 때문에 wrapper component가 매우 많아지는 단점이 있다. 해결방법은?
function **useAuth()** {
const [users, setUsers] = useState([]); **//useAuth 라는 커스텀 훅스에서 유저 데이터를 다 가져온다.**
useEffect(() => {
fetchUsers().then(users => {
setUsers(users);
});
}, []);
**return [users];**
}
function Apage() {
**const [users] = useAuth();**
return (
<div>
A 페이지
{users.map(({ name, url }) => (
<div key={name}>
<p>{name}, {url}</p>
</div>
))}
</div>
);
}