Хук контекста useContext в React

В этом уроке мы продолжим работу с контекстом. Теперь построим дерево компонентов. Для начала в отдельном файле создадим React компонент BigBox:

BigBox.jsxfunction BigBox() {
  return (
    <p>bigbox</p>
  );
}

Импортируем его и разместим в нашем главном компоненте App:

App.jsximport BigBox from './BigBox';

function App() {
  return (
    <BigBox />
  );
}

Для большей наглядности немного стилизуем дивы. Для этого создадим файл styles.css:

styles.cssdiv {
  border: 1px solid blue;
  margin: 10px;
  text-align: center;
  max-width: 300px;
}

Не забудем импортировать его в App.js:

App.jsximport './styles.css';

Теперь в отдельном файле создадим компонент MiddleBox:

MiddleBox.jsxfunction MiddleBox() {
  return (
    <p>middlebox</p>
  );
}

И положим его в большую коробку BigBox:

BigBox.jsximport MiddleBox from './MiddleBox';

function BigBox() {
  return (
    <div>
      <MiddleBox />
    </div>
  );
}

Проделаем все тоже самое с маленькой коробочкой SmallBox:

SmallBox.jsxfunction SmallBox() {
  return (
    <p>I am ... </p>
  );
}

Разместим две таких коробочки в MiddleBox:

MiddleBox.jsximport SmallBox from './SmallBox';

function MiddleBox() {
  return (
    <div>
      <SmallBox />
      <SmallBox />
    </div>
  );
}

Дерево мы построили. А теперь мы хотим от нашего App передать, предположим, в SmallBox строковое значение 'small box :)', не используя пропсы, а пользуясь контекстом (вдруг наше коробочное приложение разрастется до огромных размеров).

Файл с контекстом MyContext.js мы уже создали и подключили на прошлом уроке.

Следующий шаг, который мы сделаем - обернем BigBox в провайдер контекста, который является свойством нашего объекта контекста MyContext. Теперь все компоненты, заключенные в данную конструкцию (а это и все коробочки, вложенные в BigBox) смогут получить доступ и подписаться на изменения контекста. В качестве значения контекста мы передаем желаемое 'small box :)':

App.jsxfunction App() {
  return (
    <MyContext.Provider value="small box :)">
      <BigBox />
    </MyContext.Provider>
  );
}

А теперь осталось прочитать значение контекста. Мы хотели использовать его в SmallBox, значит импортируем туда файл контекста MyContext.js и хук useContext:

SmallBox.jsximport { useContext } from 'react';
import { MyContext } from './MyContext.js';

Прочитаем с помощью useContext значение контекста в переменную name:

SmallBox.jsxfunction SmallBox() {
  const name = useContext(MyContext);
  
  return (
    <div>
      <p>I am ... </p>
    </div>
  );
}

Мы подписали SmallBox на данный контекст и, если он изменится, этот компонент также будет обновлен.

И, наконец, подставляем значение переменной name вместо многоточия:

SmallBox.jsxfunction SmallBox() {
  const name = useContext(MyContext);
  
  return (
    <div>
      <p>I am {name} </p>
    </div>
  );
}
Задание 1

В пустом компоненте App создайте компонент Parent, а в нем компонент Daughter, а в Daughter компонент Grandson. Используя контекст, передайте из App значение возраста 42, а с помощью useContext выведите его в компоненте Daughter.

Задание 2

А теперь в компоненте Grandson выведите значение возраста, но поделенное на 2.