React Context과 useContext

송승찬·2020년 9월 30일
0

TIL

목록 보기
38/52
post-thumbnail

React Context는 전역 데이터를 담고 있는 하나의 저장 공간

왜 필요한가?
다음의 코드를 봐보자

import React from 'react';

export default function App () {
    return (
        <div>
            <div>상단</div>
            <Profile name='Seung-chan' />
            <div>하단</div>
        </div>
    )
}

function Profile ({name}) {
    return (
        <div>
            <Greeting name={name} />
        </div>
    )
}
function Greeting ({name}) {
    return (
        <p>{name}님 안녕하세요!</p>
    )
}

위의 코드에서 Profile은 어떤 UI도 그리지 않고, 단지 name을 전달하는 역할만 함에도 Greeting에 {name}속성값의 전달을 위해 사용,즉 컴포넌트를 2번 거쳐써야함
그렇다면 전역으로 데이터를 관리하게 한다면 이런 일이 필요 X, 따라서 전역 데이터를 담고 있는 하나의 저장 공간인 Context를 사용함

useContext의 사용은 다음을 따른다
1. createContext()로 컨텍스트 생성
2. 컴포넌트에 Provider제공(Provider를 선언하게 되면, 해당 Provider의 자식들은 value에 선언된 부분들을 props로 넘겨주지 않아도 사용가능)
3. useContext(context)통한 값 가져오기
(여기서 useContext()의 반환값은 <Context.Provider value={} />의 value에 전달한 값, 또한 Provider의 value속성은 value라는 이름으로 꼭 써주자)

import React,{createContext,useContext} from 'react';

const UserContext = createContext();
const userInfo = {name:'Seung-chan',location:'Korea'}
export default function App () {
        return (
        <div>
            <UserContext.Provider value={userInfo}>
                <div>상단</div>
                <Profile />
                <div>하단</div>
            </UserContext.Provider>
        </div>
    )
}

function Profile () {
    return (
        <div>
            <Greeting  />
        </div>
    )
}
function Greeting () {
    
    즉, <UserContext.Priovider value={userInfo} /> => value에 저장된 값이 useContext의 return 값,즉 여기서는 userInfo = {name:'Seung-chan',location:'Korea'} 객체
    
    const {name,location} = useContext(UserContext);
    console.log('Info:',name,location);
    return (        
        <p>{name}님 안녕하세요! {location}에 있군요</p>
    )
}

결과

ex2)

import React,{createContext,useContext} from 'react';

const AppContext = createContext();
export default function User () {
    const user = {
        name : 'Seung-chan',
        isAdmin : true
    }
    return (
        <div>
            <AppContext.Provider value={user}>
                <div>
                    <Posts />
                </div>
            </AppContext.Provider>
        </div>
    )
}

const PostContext = createContext();
const Posts = () => {
    const posts = [
        {
          title: 'useContext에 깊이 빠져봅시다',
          content: '서울은 살기 좋은 유구의 도시입니다'
        }
      ]
    return (
        <div>
            <PostContext.Provider value={posts}>
                <Children />
            </PostContext.Provider>
        </div>
    )
}

const Children =  () => {
    const user = useContext(AppContext);
    const post = useContext(PostContext);
    console.log('user:',user);   //user: {name: "Seung-chan", isAdmin: true}
    console.log('post:',post); //post: [ {title: 'useContext에 깊이 빠져봅시다', content: '서울은 살기 좋은 유구의 도시입니다'}]
    let label = 'user';
    if (user.isAdmin) {
        label = 'admin'
    }
    return (
        <div>
            <div>{label}</div>
            <div>{user.name}</div>
            <div>{post.map((v,i)=>(
                <div key={i}>
                    <div>{v.title}</div>
                    <div>{v.content}</div>
                </div>
            ))}
            </div>
        </div>
    )
}

결과

위의 코드에서 유일하게 바꾼 부분
const Profile = React.memo(() => {
    console.log('Profile');
    return (
        <div>
            <Greeting  />
        </div>
    )
});

다음과 같이 React.memo를 이용해서 Profile컴포넌트가
처음만 렌더링 후,Profile본인의 props가 변할 때만 렌더링되게 할 수도 있다.

참고 : https://velog.io/@public_danuel/trendy-react-usecontext

profile
superfly

0개의 댓글