Автор оригинала: Maksim Ivanov.
Первоначально опубликовано на maksimivanov.com.
В реактивных приложениях данных и обработчикам событий передаются до детских компонентов через реквизиты. Но иногда вам нужно сделать некоторые данные доступными на нескольких уровнях одновременно.
Передача данных через реквизиты вручную может быть громоздким.
Чтобы решить эту проблему RECT, обеспечивает контекст API.
Вы создаете контекст, используя rection.createContext (). Этот метод возвращает объект контекста:
{ Provider, Consumer; }
Проще говоря, это два компонента поставщика и потребитель. Вы передаете данные в провайдер, а затем вы можете получить доступ к этому из подключенного потребителя. контекст API
Вот простой пример.
import React, { createContext } from "react"; const { Provider, Consumer } = createContext(); // We use destructuring assignment to get Provide and Consumer const App = () => (); // Inside our app we wrap components that will need the data // into our Provider const ChildComponent = () => ( {value => { // Consumer requires a function as a child // and passes the `value` from Provider // down to it. }} );
Мы можем использовать Потребитель
на любом уровне гнездования.
Он получает данные из этого провайдера где угодно вниз по дереву.
Одно важное замечание здесь, что Потребитель
Получу только данные из Провайдер
Это было создано с.
Передача значение по умолчанию
Вы можете передать значение по умолчанию для Ract.createContext
:
const { Provider, Consumer } = React.createContext(defaultValue);
Это повлияет на только потребитель, и только если у него не будет соответствовать Провайдер
где-то над ним на дереве.
В этом случае значение по умолчанию будет передан Потребитель
Функция:
{defaultValue => { // some code }}
Динамические значения
Все потребители, которые являются потомками Провайдер
будет повторно представить всякий раз, когда поставщик ценность
Опоры меняются.
Вот пример:
Counter-context.jsx.
import React, { createContext } from "react"; const { Provider, Consumer: CounterConsumer } = createContext(0); class CounterProvider extends React.Component { state = { counter: 0 }; componentDidMount() { this.tickInterval = setInterval(() => { this.setState({ counter: this.state.counter + 1 }); }, 500); } componentWillUnmount() { clearInterval(this.tickInterval); } render() {{this.props.children} ; } } export { CounterProvider, CounterConsumer };
counter-piew.jsx.
import React, { Component } from "react"; import { CounterConsumer } from "./counter-context"; export const CounterView = () => ({counter => );Current tick: {counter}
}
app.js.
import React, { Component } from "react"; import { CounterProvider, CounterConsumer } from "./counter-context"; class App extends Component { render() { return <>; } } ReactDOM.render( , document.root);
В этом примере первая Counceway
будет обновляться на каждом тике.
Второй всегда будет отображать значение по умолчанию, потому что у него нет соответствующих Провайдер
в дереве.
Прохождение функций
Вы также можете пропускать функции через контекст. Это полезно, если вы хотите обновить Провайдер
Значение от Потребители Отказ
auth.jsx.
import React, { Component, createContext } from "react"; const { Provider, Consumer: AuthConsumer } = createContext({ loggedIn: false }); class AuthProvider extends Component { state = { loggedIn: false }; logIn = () => { this.setState({ loggedIn: true }); }; render() { return ({this.children} ); } } export { AuthProvider, AuthConsumer };
Здесь мы создали контекст и использовали Разрушение задания создать две переменные Провайдер
и Authconsumer
Отказ
Создать переменную Authconsumer
Мы переименованы в оригинал Потребитель
что мы Гон от Ract.createContext
метод.
Тогда мы определили класс AuthProvider
который управляет государством разрешения. Это касается детей в Провайдер
и проходит logugedin
Государство и Вход
Функция к этому Провайдер
Отказ
app.jsx.
import React from "react"; import { AuthProvider, AuthConsumer } from "./auth"; const App = () => (); const Content = () => { {({ loggedIn, logIn }) => loggedIn ? ( ; };Congrats! You are logged in!
) : ( ) }
Используя несколько контекстов
Можно использовать несколько контекстов одновременно.
Но вам придется использовать отдельный потребитель для каждого провайдера:
import React from "react"; const AuthContext = React.createContext({ loggedIn: false }); const ProfileContext = React.createContext({ name: "Tom" }); const App = () => (); function Content() { return ( {({ loggedIn }) => ( ); }{user => loggedIn ? ( )}Logged as: {user.name}
) : (You are not logged in
) }
Это требуется путем реагирования на сохранение каждого потребителя отдельный узел в дереве.
Когда использовать контекст
Вы должны рассмотреть возможность использования API React Context API, когда у вас есть некоторые данные, и, возможно, обратные вызовы, которые вам необходимо делиться несколькими компонентами, но вам придется пройти через слои компонентов, которые не нуждаются в этих данных или обратных вызовах.