[리액트 네이티브] 7장 Context API

minkyung·2024년 1월 20일
0
post-thumbnail

처음 배우는 리액트 네이티브 - 김범준

7장 Context API

7.1 전역 상태 관리

Context API를 이용하면 Context를 생성해 필요한 컴포넌트에서 데이터를 바로 받아올 수 있음
props로 데이터 전달 시 App > A > B > D
이렇게 중간 과정을 거치지 않고 Context를 생성해 바로 원하는 컴포넌트로 데이터 전달

7.2 Context API

기본 형태

const Context = createContext(defaultValue);

7.2.1 Consumer

src/contexts/User.js

import { createContext } from "react";

const UserContext = createContext({ name: 'mk' });

export default UserContext;

기본 값으로 mk가 설정됨

src/components/User.js

import React from "react";
import styled from "styled-components/native";
import UserContext from "../contexts/User";

const StyledText = styled.Text`
    font-size: 24px;
    margin: 10px;
`;

const User = () => {
    return (
        <UserContext.Consumer>
            {value => <StyledText>Name: {value.name}</StyledText>}
        </UserContext.Consumer>
    );
};

export default User;

Consumer

  • 상위 컴포넌트 중 가장 가까운 곳에 있는 Provider 컴포넌트가 전달하는 데이터를 이용
  • Provider가 없으면 createContext 함수 파라미터 값인 기본값을 사용
  • Consumer 컴포넌트의 자식은 반드시 리액트 컴포넌트를 반환하는 함수여야함
  • 함수는 Context의 현재값을 파라미터로 전달받아 데이터를 사용

7.2.2 Provider

const App = () => {
    return (
    <UserContext.Provider value={{ name: 'mkcyb' }}>
        <Container>
            <User />
        </Container>
    </UserContext.Provider>
    );
};

Provider

  • 하위 컴포넌트에 Context의 변화를 알리는 역할

  • Provider 컴포넌트는 value를 받아서 모든 하위 컴포넌트에 전달, 자식 컴포넌트는 Provider 컴포넌트의 value가 변경될 때마다 다시 렌더링

  • Provider 컴포넌트로부터 value를 전달받는 하위 컴포넌트 수 제한 x

  • Provider 컴포넌트를 사용할 때 반드시 value를 지정해야 함

  • Consumer 컴포넌트는 가장 가까운 Provider 컴포넌트가 전달하는 값을 사용

7.2.3 Context 수정하기

src/contexts/User.js

import { createContext, useState } from "react";

const UserContext = createContext({
    user: { name: '' },
    dispatch: () => {},
});

const UserProvider = ({ children }) => {
    const [name, setName] = useState('mk-cyb');

    const value = { user: {name}, dispatch: setName};
    return <UserContext.Provider value={value}>{children}</UserContext.Provider>
};

const UserConsumer = UserContext.Consumer;

export { UserProvider, UserConsumer };

export default UserContext;
  • Provider 컴포넌트의 value에 전역으로 관리할 상태변수와 상태 변경 함수를 함께 전달하는 UserProvider 컴포넌트
  • createContext의 기본값도 UserProvider 컴포넌트의 value로 전달하는 형태와 동일한 형태를 갖도록 함

Input 컴포넌트

import React, { useState } from "react";
import styled from "styled-components/native";
import { UserConsumer } from "../contexts/User";

const StyledInput = styled.TextInput`
    border: 1px solid #606060;
    width: 250px;
    padding: 10px 15px;
    margin: 10px;
    font-size: 24px;
`

const Input = () => {
    const [name, setName] = useState('');

    return (
        <UserConsumer>
            {({ dispatch }) => {
                return (
                    <StyledInput
                        value={name}
                        onChangeText={text => setName(text)}
                        onSubmitEditing={() => {
                            dispatch(name);
                            setName('');
                        }}
                        placeholder="Enter a name..."
                        autoCapitalize="none"
                        autoCorrect={false}
                        returnKeyType="done"
                        />
                );
            }}
        </UserConsumer>

    );
};
export default Input;
  • UserProvider 컴포넌트의 value로 전달되는 세터함수를 이용해 입력되는 값으로 Context의 값을 변경하는 Input 컴포넌트
  • UserConsumer의 컴포넌트의 자식 함수에 전달되는 value에는 dispatch 함수가 같이 전달됨
  • dispatch를 이용해 키보드의 확인버튼을 누르면 TextInput에 입력된 입력값으로 Context의 값을 변경

7.3 useContext

useContext 함수는 Consumer 컴포넌트의 자식 함수로 전달도던 값과 동일한 데이터를 반환
Consumer 컴포넌트를 사용하지 않고 Context의 내용을 사용 가능
src/components/User.js

import React, { useContext } from "react";
...
const User = () => {
    const { user } = useContext(UserContext);
    return <StyledText>Name: {user.name}</StyledText>;
};
...

src/components/Input.js

import React, { useState, useContext } from "react";
...
const Input = () => {
    const [name, setName] = useState('');
    const { dispatch } = useContext(UserContext);

    return (
        <StyledInput
            value={name}
            onChangeText={text => setName(text)}
            onSubmitEditing={() => {
                dispatch(name);
                setName('');
            }}
            placeholder="Enter a name..."
            autoCapitalize="none"
            autoCorrect={false}
            returnKeyType="done"
            />
    );
};
...
  • Consumer를 사용할 때
    • 자식으로 반드시 리액트 컴포넌트를 반환하는 함수를 넣어야함
  • useContext 사용
    • 코드의 가독성 좋아짐
    • 사용법이 간편
profile
개발/보안 기록용

0개의 댓글