리액트 네이티브에서 사용되는 Data는 윗 Component 에서 Nested Component 로 Depth를 이뤄가면 전달되는 방식이기 때문에 쓸데없이 중간 Component 들이 Props를 받아야 하는 어러움이 있다.
이걸 해결해주는게 Hook 의 Context 이다.
UseContext 사용하지 않는 코드
아래 샘플 코드는 Context를 사용하지 않고 기존의 방식대로 Component에게 정보를 전달한다.
import React, { Fragment,useState,useEffect } from 'react';
import OldComponent from './SharedContext/OldComponet';
const App =()=>{
const [user, setUser] = useState({
user_id:"",
user_email:"",
})
const fetchUser = () =>{
setTimeout(()=>{
setUser({user_id:"test",user_email:"test@naver.com"})
},1000)
}
useEffect(() => {
fetchUser()
}, [])
return(
<OldComponent user={user}/>
)
}
export default App
App.js 에서 user 정보를 1초후에 셋업하고 이 정보를 OldComponent에게 user 라는 Props 이름으로 전달한다.
OldComponent.js
import OldComponentEnd from './OldComponent_End'
const OldComponent =(props)=>{
return(
<OldComponentEnd user={props.user}/>
)
}
export default OldComponent
OldComponent 는 OldComponentEnd를 렌더링하고, user 정보를 사용하기 위해 App.js 에서 받은 props.user를 OldComponentEnd로 전달해준다.
OldComponent_End.js
import React from 'react'
import { Fragment } from 'react'
const OldComponentEnd =(props)=>{
return(
<Fragment>
<li>User : {props.user.user_id}</li>
<li>User Email : {props.user.user_email}</li>
</Fragment>
)
}
export default OldComponentEnd
OldComponent_End.js
import React from 'react'
import { Fragment } from 'react'
const OldComponentEnd =(props)=>{
return(
<Fragment>
<li>User : {props.user.user_id}</li>
<li>User Email : {props.user.user_email}</li>
</Fragment>
)
}
export default OldComponentEnd
마지막으로 화면에 표시할 OldComponent_End 에서는 App.js 에서 받은 정보를 그려주고 있다.
여기에서 OldComponent는 단순히 App.js 에서 받은 User를 OldComponent_End 로 전달해 주고만 있을 뿐 사용하고 있지 않다. 만일 이러한 Nested Component가 수가 많아지면 단순히 Data 전달만을 위해서 필요없는 단계들이 수 없이 많아 질수 도 있다.
위 코드를 Context를 이용한 코드로 수정하면
UseContext사용 코드
SharedContext.js
import React,{useState, createContext} from 'react'
const MyContext = createContext()
const SharedContextProvider=(props)=>{
console.log(props.value)
return(
<MyContext.Provider value = {props.value}>
{props.children}
</MyContext.Provider>
)
}
const SharedContextConsumer=(props)=>{
return(
<MyContext.Consumer >
{props.children}
</MyContext.Consumer>
)
}
export {SharedContextConsumer,SharedContextProvider}
일단 전역으로 사용할 ContextProvider 와 ContextConsumer Component 들을 만들어 준다.
MyContext.Provider 는 value 는 컴포넌트에서 주입될 value를 사용하고, 안에 render 될 Component 는 또 한, props.children 으로 그대로 받아서 사용한다.
MyContext.Consumer 또한 children 을 그대로 그려준다
App.js
import React, { Fragment,useState,useEffect } from 'react';
import NewComponent from './SharedContextComponent/NewComponent';
import { SharedContextProvider } from './SharedContextComponent/SharedContext';
const App =()=>{
const [user, setUser] = useState({
user_id:"",
user_email:"",
})
const fetchUser = () =>{
setTimeout(()=>{
setUser({user_id:"test",user_email:"test@naver.com"})
},1000)
}
useEffect(() => {
fetchUser()
}, [])
return(
<SharedContextProvider value={user}>
<NewComponent/>
</SharedContextProvider>
)
}
export default App
NewComponent.js
import React from 'react'
import NewComponentEnd from './NewComponet_End'
const NewComponent =(props)=>{
return(
<NewComponentEnd/>
)
}
export default NewComponent
NewComponent_End.js
import React from 'react'
import { SharedContextConsumer } from './SharedContext'
const NewComponentEnd=()=>{
return(
<SharedContextConsumer>
{value =><div>
{<li>user_id : {value.user_id}</li>}
{<li>user_email : {value.user_email}</li>}
</div>}
</SharedContextConsumer>
)
}
export default NewComponentEnd
이렇게 사용하면 중간의 NewComponent를 거치지 않고서도 사용하고자 하는 Component에서 user의 값을 사용할 수 있습니다.