Written by
Lee Jongseo
on
on
Data fetching with HOC
Data fetching
컴포넌트를 렌더링할 때 로컬 데이터나 API를 통해서 fetching 하여 View에 주입한다.
mount => fetching => view(re-render) 흐름으로 가야하기 때문에
클래스형 컴포넌트의 componentDidMount()
메소드나 함수형 컴포넌트의 useEffect()
훅 안에서
data fetching을 해야 한다.
fetching example
// 클래스형
class MyComponent extends React.Component {
constructor() {
//
}
async componentDidMount() {
// data fetching
}
}
// 함수형
const MyComponent = () => {
useEffect(() => {
async dataFetching() {
// data fetching
}
dataFetching()
})
return (
//
)
}
HOC
data fetching이 필요한 컴포넌트마다 fetching logic을 담게 되면 재사용가능한 컴포넌트를 만들 수 없게 된다.
따라서 fetching logic을 따로 분리하고 fetching이 필요한 컴포넌트가 있으면 해당 logic을 사용할 수 있게 하는 것이 좋은데
Higher Order Component를 사용하여 이를 수행할 수 있다.
Higher Order Component(HOC)는 컴포넌트를 반환하는 함수를 말한다.
Creating HOC
HOC의 모습은 다음과 같다.
// 클래스형 컴포넌트 반환
function withDataFetching(Component) {
return class extends React.Component {
constructor(props) {
super(props)
// set state
}
// other life cycle methods
render() {
<Component />
}
}
}
// 함수형 컴포넌트 반환
function withDataFetching(Component) {
// fetching data
return <Component />
}
컴포넌트를 반환하는 함수를 작성하면 된다.
함수 내에서 data fetching logic을 작성하면 된다.
fetching with HOC
// withDataFetching.js
export default function withDataFetching(Component) {
return class extends React.Component {
constructor(props) {
super(props)
this.state = {
data: [],
loading: true,
error: ''
}
}
async componentDidMount() {
try{
const response = await fetch(this.props.url)
const dataJSON = await response.json()
if (dataJSON) {
this.setState({
data: dataJSON,
loading: false
})
}
} catch(err) {
this.setState({
loading: false,
error: err.message
})
}
}
render() {
const {data ,loading, error} = this.state
return <Component data={data} loading={loading} error={error} {...this.props} />
}
}
}
fetching한 데이터를 컴포넌트에 props로 전달한다.
Using HOC
정의한 HOC를 fetching이 필요한 컴포넌트에 사용한다.
const MyComponent = ({data, loading, error}) => {
return (
<ul>
{
data.map(item => <li key={item.id}>{item.body}</li>)
}
</ul>
)
}
export default withDataFetching(MyComponent)