Многие языки шаблонов имеют операторы «slots» или «yield», которые позволяют выполнять какое-то обращение управления, чтобы обернуть один шаблон внутри другого.
Angular имеет опцию «transclude» .
У Rails есть заявление о выходе . Если бы в React.js был оператор yield, он бы выглядел так:
var Wrapper = React.createClass({
render: function() {
return (
<div className="wrapper">
before
<yield/>
after
</div>
);
}
});
var Main = React.createClass({
render: function() {
return (
<Wrapper><h1>content</h1></Wrapper>
);
}
});
Желаемый вывод:
<div class="wrapper">
before
<h1>content</h1>
after
</div>
Увы, React.js не имеет <yield/>
. Как определить компонент Wrapper для достижения того же результата?
Ответы:
Пытаться:
Посмотрите Многократные Компоненты: Дети и Тип реквизита Детей в документах для получения дополнительной информации.
источник
С помощью
children
Это также известно как
transclusion
в Angular.children
является специальной опорой в React и будет содержать то, что находится внутри тегов вашего компонента (здесь<App name={name}/>
внутриWrapper
, так что этоchildren
Обратите внимание, что вам не обязательно использовать его
children
, который является уникальным для компонента, и вы можете использовать обычные реквизиты, если хотите, или смешивать реквизиты и дочерние элементы:Это просто и хорошо для многих случаев использования, и я рекомендую это для большинства потребительских приложений.
сделать реквизит
Можно передать функции рендеринга компоненту, этот шаблон обычно вызывается
render prop
, иchildren
реквизит часто используется для обеспечения этого обратного вызова.Этот шаблон не предназначен для макета. Компонент-обертка обычно используется для хранения и управления некоторым состоянием и добавления его в функции рендеринга.
Встречный пример:
Вы можете получить еще больше фантазии и даже предоставить объект
Обратите внимание, что вам не обязательно использовать
children
, это вопрос вкуса / API.На сегодняшний день многие библиотеки используют реквизит рендеринга (контекст React, React-motion, Apollo ...), потому что люди склонны находить этот API проще, чем HOC. response-powerplug - это набор простых компонентов render-prop. Реакция-принятие помогает вам сделать композицию.
Компоненты высшего порядка (HOC).
Higher-Order Компонент / HOC , как правило , функция , которая принимает компонент и возвращает новый компонент.
Использование компонента высшего порядка может быть более производительным, чем использование
children
илиrender props
, потому что оболочка может иметь возможность замкнуть рендеринг на шаг впередиshouldComponentUpdate
.Здесь мы используем
PureComponent
. При повторном рендеринге приложения, еслиWrappedApp
имя prop не изменяется со временем, оболочка может сказать: «Мне не нужно рендерить, потому что реквизиты (фактически, имя) такие же, как и раньше». При использованииchildren
приведенного выше решения, даже если это оболочкаPureComponent
, это не так, потому что дочерний элемент воссоздается каждый раз, когда создается родительский элемент, что означает, что оболочка, вероятно, всегда будет повторно отображаться, даже если упакованный компонент будет чистым. Существует плагин Babel, который может помочь смягчить это и обеспечить постоянныйchildren
элемент с течением времени.Вывод
Компоненты высшего порядка могут дать вам лучшую производительность. Это не так сложно, но поначалу это выглядит недружелюбно.
Не переносите всю кодовую базу в HOC после прочтения этого. Просто помните, что на критических путях вашего приложения вы можете захотеть использовать HOC вместо оболочек времени выполнения по соображениям производительности, особенно если одна и та же оболочка используется много раз, стоит подумать о том, чтобы сделать ее HOC.
Redux сначала использовал оболочку времени выполнения,
<Connect>
а затем переключился на HOCconnect(options)(Comp)
по соображениям производительности (по умолчанию оболочка чистая и используетсяshouldComponentUpdate
). Это отличная иллюстрация того, что я хотел выделить в этом ответе.Обратите внимание, что если у компонента есть API рендеринга-пропа, поверх него обычно легко создать HOC, поэтому, если вы являетесь автором lib, вы должны сначала написать API-интерфейс рендеринга и в конечном итоге предложить версию HOC. Это то, что Apollo делает с
<Query>
компонентом render-prop и сgraphql
помощью HOC.Лично я использую оба, но когда сомневаюсь, я предпочитаю HOC, потому что:
compose(hoc1,hoc2)(Comp)
) более идиоматично по сравнению с реквизитами рендерингаЯ без колебаний использую / создаю HOC версии моих любимых инструментов:
Context.Consumer
компSubscribe
graphql
HOC Аполлона вместоQuery
рендера пропНа мой взгляд, иногда реквизит рендеринга делает код более читабельным, иногда меньше ... Я стараюсь использовать наиболее прагматичное решение в соответствии с имеющимися у меня ограничениями. Иногда читаемость важнее исполнения, иногда нет. Выбирайте мудро и не следуйте тенденции 2018 года по конвертации всего в рендер-реквизит.
источник
В дополнение к ответу Софи я также нашел применение при отправке дочерних типов компонентов, делая что-то вроде этого:
источник
delegate
том, как вы ее нашли?