Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?

Контекст и хук useContext

В React существует проблема передачи свойств целевым компонентам. Обычно мы поднимаем данные по дереву компонентов, чтобы хранить их в одном месте. Но затем их приходится спускать вниз по цепочке пропсов для вывода на страницу. Иногда несколько уровней компонентов просто передают вниз ненужные им данные. чтобы они достигли цели.

function App() {
  // храним данные пользователя в App
  // но выводим в Header
  const [user] = React.useState({ name: "Fred" });

  return (
   {/* Первый уровень передачи данных через незаинтересованный компонент Main */}
    <Main user={user} />
  );
}

const Main = ({ user }) => (
  <>
    {/* Второй уровень передачи данных */}
    <Header user={user} />
    <div>Main app content...</div>
  </>
);

const Header = ({ user }) => <header>Welcome, {user.name}!</header>;

Чтобы избежать этого, можно воспользоваться React-концепцией контекста. Это общая область видимости для целого дерева компонентов.

// Создаем контекст для данных юзера
const UserContext = React.createContext();

function App() {
  // Создаем состояние для хранения данных юзера
  const [user] = React.useState({ name: "Fred" });

  return (
    {/* Оборачиваем родительский компонент в провайдер контекста */}
    {/* Теперь данные юзера доступны всем дочерним компонентам */}
    <UserContext.Provider value={user}>
      <Main />
    </UserContext.Provider>
  );
}

const Main = () => (
  <>
    <Header />
    <div>Main app content...</div>
  </>
);

// Вместо пропсов используем UserContext.Consumer
const Header = () => (
  <UserContext.Consumer>
    {user => <header>Welcome, {user.name}!</header>}
  </UserContext.Consumer>
);

С хуком useContext все становится еще проще:

const Header = () => {
  // Помещаем контекст в переменную user
  const user = React.useContext(UserContext);
  // Избавляемся от обертки UserContext.Consumer
  return <header>Welcome, {user.name}!</header>;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment