Пожалуй, самый простой способ - описать аналогичное понятие: функция декоратор.
// Start with a function, any function.
let add = (a, b) => a + b;
Но теперь мы хотим добавить логирование для аргументов и вернуть:
let addWithLogging = (a, b) => {
console.log("Args are ", a, b);
const result = a + b;
console.log("Result is ", result);
return result;
}
Barf. Наша простая однострочная функция теперь усложняется кучей вещей, которые совершенно случайны при добавлении двух чисел. Если большинство наших функций просты, и мы хотим добавить протоколирование ко всем из них, вычисление за пределами конверта состоит в том, что наша кодовая база удвоится. Двойной барф.
Но подождите, это JavaScript, у нас есть функции высшего порядка и мы можем извлечь декоратор:
// Here we take a function f and wrap it. We'll return a function that will
// collect the arguments, log them, perform f on them, log the result, and
// then finally return that result to the caller.
const withLogging = f => (...args) => {
console.log("Args are ", ...args);
const result = f(...args);
console.log("Result is ", result);
return result;
};
addWithLogging = withLogging(add);
React использует эту же идею с компонентами более высокого порядка, у вас есть компонент, который нуждается в некоторой дополнительной функциональности (часто это состояние и / или выполнение AJAX-вызовов). Вы не хотите все этим усложнять свой чистый простой тестируемый чисто функциональный компонент, поэтому вместо него вы используете компонент более высокого порядка. Как и описанный выше декоратор логирования, компонент более высокого порядка в вашем примере принимает компонент в качестве аргумента и возвращает анонимный чисто функциональный компонент, который фактически получает реквизиты и отображает переданный компонент, заключенный в компонент UserContext.
Вы могли бы просто сделать компонент UserContext частью JSX, возвращенного другим компонентом:
const UserAvatar = ({ user, size }) => (
<UserContext.Consumer>
<img
className={`user-avatar ${size || ""}`}
alt="user avatar"
src={user.avatar}
/>
</UserContext.Consumer>
);
Но теперь, как и в примере с журналированием, вы повторяете шаблон в каждом компоненте, который в этом нуждается.
Что касается конкретной строки, на которую вы ссылаетесь, возможно, вам там не нужна функция, потому что, насколько я могу судить, user
уже находится в props
, когда компонент отображается. Для справки вот скомпилированный JSX .
EDIT
Должен был прочитать код более внимательно.
Причина, по которой вам нужна функция, заключается в том, что она является потребителем контекста. user
вводится через провайдера контекста, и единственный способ сделать это - предоставить ему функцию для передачи аргументов.