Перейти к содержанию

createContext

createContext позволяет вам создать контекст, который компоненты могут предоставить или прочитать.

1
const SomeContext = createContext(defaultValue);

Описание

createContext(defaultValue)

Вызовите createContext вне каких-либо компонентов для создания контекста.

1
2
3
import { createContext } from 'react';

const ThemeContext = createContext('light');

Параметры

  • defaultValue: Значение, которое вы хотите, чтобы контекст имел, если в дереве над компонентом, читающим контекст, нет подходящего поставщика контекста. Если у вас нет никакого значимого значения по умолчанию, укажите null. Значение по умолчанию используется в качестве запасного варианта "на крайний случай". Оно статично и никогда не изменяется с течением времени.

Возвращает

createContext возвращает объект контекста.

Сам объект контекста не содержит никакой информации. Он представляет какой контекст читают или предоставляют другие компоненты. Обычно вы используете SomeContext.Provider в компонентах выше, чтобы указать значение контекста, и вызываете useContext(SomeContext) в компонентах ниже, чтобы прочитать его. Объект контекста имеет несколько свойств:

  • SomeContext.Provider позволяет вам предоставлять значение контекста компонентам.
  • SomeContext.Consumer является альтернативным и редко используемым способом чтения значения контекста.

SomeContext.Provider

Оберните ваши компоненты в провайдер контекста, чтобы указать значение этого контекста для всех компонентов внутри:

1
2
3
4
5
6
7
8
9
function App() {
    const [theme, setTheme] = useState('light');
    // ...
    return (
        <ThemeContext.Provider value={theme}>
            <Page />
        </ThemeContext.Provider>
    );
}

Параметры

  • value: Значение, которое вы хотите передать всем компонентам, читающим данный контекст внутри данного провайдера, независимо от его глубины. Значение контекста может быть любого типа. Компонент, вызывающий useContext(SomeContext) внутри провайдера, получает value самого внутреннего соответствующего провайдера контекста над ним.

SomeContext.Consumer

До появления useContext существовал более старый способ чтения контекста:

1
2
3
4
5
6
7
8
function Button() {
    // 🟡 Legacy way (not recommended)
    return (
        <ThemeContext.Consumer>
            {(theme) => <button className={theme} />}
        </ThemeContext.Consumer>
    );
}

Хотя этот старый способ все еще работает, но новый написанный код должен читать контекст с помощью useContext() вместо этого:

1
2
3
4
5
function Button() {
    // ✅ Recommended way
    const theme = useContext(ThemeContext);
    return <button className={theme} />;
}

Параметры

  • children: Функция. React будет вызывать переданную вами функцию с текущим значением контекста, определяемым по тому же алгоритму, что и useContext(), и отображать результат, возвращаемый этой функцией. React также будет повторно запускать эту функцию и обновлять пользовательский интерфейс при каждом изменении контекста из родительских компонентов.

Использование

Создание контекста

Контекст позволяет компонентам передавать информацию вглубь без явной передачи пропсов.

Вызовите createContext вне любых компонентов для создания одного или нескольких контекстов.

1
2
3
4
import { createContext } from 'react';

const ThemeContext = createContext('light');
const AuthContext = createContext(null);

createContext возвращает объект контекста. Компоненты могут читать контекст, передавая его в useContext():

1
2
3
4
5
6
7
8
9
function Button() {
    const theme = useContext(ThemeContext);
    // ...
}

function Profile() {
    const currentUser = useContext(AuthContext);
    // ...
}

По умолчанию, значения, которые они получают, будут значениями по умолчанию, которые вы указали при создании контекстов. Однако, само по себе это не полезно, потому что значения по умолчанию никогда не меняются.

Контекст полезен, потому что вы можете предоставить другие, динамические значения из ваших компонентов:.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
function App() {
    const [theme, setTheme] = useState('dark');
    const [currentUser, setCurrentUser] = useState({
        name: 'Taylor',
    });

    // ...

    return (
        <ThemeContext.Provider value={theme}>
            <AuthContext.Provider value={currentUser}>
                <Page />
            </AuthContext.Provider>
        </ThemeContext.Provider>
    );
}

Теперь компонент Page и все компоненты внутри него, независимо от глубины, будут "видеть" переданные значения контекста. Если переданные значения контекста изменяются, React будет перерисовывать компоненты, читающие контекст.

Подробнее о чтении и предоставлении контекста и примеры

Импорт и экспорт контекста из файла

Часто компонентам в разных файлах требуется доступ к одному и тому же контексту. Поэтому обычно контексты объявляются в отдельном файле. Затем вы можете использовать оператор export, чтобы сделать контекст доступным для других файлов:

1
2
3
4
5
// Contexts.js
import { createContext } from 'react';

export const ThemeContext = createContext('light');
export const AuthContext = createContext(null);

Компоненты, объявленные в других файлах, могут использовать оператор импорт для чтения или предоставления этого контекста:

1
2
3
4
5
6
7
// Button.js
import { ThemeContext } from './Contexts.js';

function Button() {
    const theme = useContext(ThemeContext);
    // ...
}

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// App.js
import { ThemeContext, AuthContext } from './Contexts.js';

function App() {
    // ...
    return (
        <ThemeContext.Provider value={theme}>
            <AuthContext.Provider value={currentUser}>
                <Page />
            </AuthContext.Provider>
        </ThemeContext.Provider>
    );
}

Это работает аналогично импорту и экспорту компонентов.

Устранение неполадок

Я не могу найти способ изменить значение контекста

Код, подобный этому, определяет значение контекста по умолчанию:

1
const ThemeContext = createContext('light');

Это значение никогда не меняется. React использует это значение только в качестве запасного варианта, если не может найти подходящего провайдера выше.

Чтобы контекст менялся со временем, добавьте состояние и оберните компоненты в провайдера контекста.

Источник — https://react.dev/reference/react/createContext

Комментарии