- Оригинальный адрес:Pass Multiple Children to a React Component with Slots
- Оригинальный автор:Dave Ceddia
- Перевод с:Программа перевода самородков
- Постоянная ссылка на эту статью:GitHub.com/rare earth/gold-no…
- Переводчик:Zheng7426
- Корректор:noahziheng, BillShiyaoZhang
Предположим, вам нужно написать повторно используемый компонент. Тем не менее, называетсяchildren
Опора не отвечает этому требованию. Этот компонент должен быть способен приниматьбольше, чем одиндетей, причем размещение этих детей не по соседству, а по заявке.
Вы можете написать это с заголовком, боковой панелью и блоком контента под названиемLayout
с компонент. Или вы пишете с левой и правой динамической боковой панелью.NavBar
компоненты.
Все вышеперечисленные задачи можно легко выполнить с помощью шаблона «слоты», другими словами, передав JSX в реквизит.
резюме: вы можете передать JSX вЛюбыевместо того, чтобы просто позвонитьchildren
Поддержка компонента не ограничивается встраиванием JSX в тег компонента, чтобы упростить передачу данных, но также сделать компонент более ценным для повторного использования.
Краткий обзор Children in React
Начнем с того, что React позволяет вкладывать теги JSX.childrenпуть к компонентуchildren. Эти элементы (ноль, один или несколько) будут названы в этом компонентеchildren
существует в виде реквизита. Имя реакцииchildren
Опора является эквивалентом Angular, трансклюзия там Vue<slot>
.
ВотButton
Пример компонента, передающего дочерние элементы:
<Button>
<Icon name="dollars"/>
<span>BUY NOW</span>
</Button>
Давайте подробно рассмотримButton
Реализация этого компонента и посмотрите, что он делает с детьми:
function Button(props) {
return (
<button>
{props.children}
</button>
);
}
Button
Эффективно используйте то, что вы передали раньше, с помощьюbutton
Элементы инкапсулированы. Хотя на данный момент в этом нет ничего потрясающего, это практическая способность. Это позволяет принимающему компоненту размещать дочерние элементы в любом месте макета или оборачивать его вclassName
внутри. Отрендеренный HTML-код будет выглядеть так:
<button>
<i class="fa fa-dollars"></i>
<span>BUY NOW</span>
</button>
(Кстати, здесь мы предполагаемIcon
рендеринг компонентов<i>
Этикетка. )
Дети тоже нормальная опора
React использует дочерние элементы довольно круто: вложенные элементы могут быть указаны какchildren
Реквизит, но это не магический и специальный реквизит. Вы можете дать реквизиту указать любые другие элементы. Давайте посмотрим на:
// 这行代码其实 ——
<Button children={<span>Click Me</span>} />
// 相当于以下的代码。
<Button>
<span>Click Me</span>
</Button>
Таким образом, вы можете не только передать его как обычный реквизитchildren
, вы также можете передать код JSX в свойствах. Вы удивлены? Правильно, эта функция не является эксклюзивной для реквизита под названием «дети»!
Использование реквизита с именованными слотами
Что бы вы подумали, если бы я сказал вам, что вы можете передать код JSX любой опоре?
(Ты уже знаешь секрет, не так ли?)
Вот пример использования этих реквизитов "slots" - вызов реквизита с 3 реквизитамиLayout
s компонент:
<Layout
left={<Sidebar/>}
top={<NavBar/>}
center={<Content/>}
/>
в этом имениLayout
Среди компонентов его можно использовать по желаниюleft
,top
так же какcenter
Эти три реквизита. Вот простой пример:
function Layout(props) {
return (
<div className="layout">
<div className="top">{props.top}</div>
<div className="left">{props.left}</div>
<div className="center">{props.center}</div>
</div>
);
}
Только представь,Layout
Код внутри компонента может быть очень сложным, он может иметь множество вложенных элементов.div
или имя класса Bootstrap и т. д. Этот компонент также может передавать информацию более подробным компонентам. несмотря ни на чтоLayout
что нужно сделать, его пользователи просто должны знать, как пройтиleft
,top
так же какcenter
Этих трех реквизитов достаточно.
Используйте Children для прямой передачи реквизита
Также есть приятная фича про проходящих детей (независимо от того, используется ли опораchildren
): когда вы собираетесь передать дочернюю опору, просто вparentЗатем в области вы можете передать любую информацию, которая вам нужна.
Это какпропустил уровень. Например: вместо того, чтобы передавать «пользователя» компоненту Layout, а затем передавать «пользователя» Layout компоненту NavBar, лучше создать NavBar (с уже установленным пользователем) и передать весь NavBar в Layout . Это помогает избежать проблемы «сверления реквизита», когда вам не нужно помещать реквизит в иерархию нескольких компонентов.
function App({ user }) {
return (
<div className="app">
<Nav>
<UserAvatar user={user} size="small" />
</Nav>
<Body
sidebar={<UserStats user={user} />}
content={<Content />}
/>
</div>
);
}
// 接收 children 并渲染它(们)
const Nav = ({ children }) => (
<div className="nav">
{children}
</div>
);
// Body 需要一个侧边栏和内容,如果像下面这样写的话,
// 他们可以做任何事
const Body = ({ sidebar, content }) => (
<div className="body">
<Sidebar>{sidebar}</Sidebar>
{content}
</div>
);
const Sidebar = ({ children }) => (
<div className="sidebar">
{children}
</div>
);
const Content = () => (
<div className="content">main content here</div>
);
Теперь сравните со следующей записью, и Nav, и Body принимают имяuser
, то они несут ответственность за ручную передачу реквизита дочерним элементам. После этого их дети должны быть переданы на более высокий уровень детей...
function App({ user }) {
return (
<div className="app">
<Nav user={user} />
<Body user={user} />
</div>
);
}
const Content = () => <div className="content">main content here</div>;
const Sidebar = ({ user }) => (
<div className="sidebar">
<UserStats user={user} />
</div>
);
const Body = ({ user }) => (
<div className="body">
<Sidebar user={user} />
<Content user={user} />
</div>
);
const Nav = ({ user }) => (
<div className="nav">
<UserAvatar user={user} size="small" />
</div>
);
Это не так удобно, как раньше, не так ли? Передача реквизита таким образом (также известная как «сверление реквизита») оставляет компоненты увязшими в слишком большом количестве хлопот, которые вам, вероятно, не нужны — не всегда плохо, но вам лучше выяснить, что происходит между ними. Как они связаны. Первое использование дочерних элементов выше позволяет избежать необходимости в более сложных решениях, таких как контекст, Redux или MobX (среди многих других).
Остерегайтесь PureComponent или shouldComponentUpdate
Если вам нужно реализовать компонент с дочерними элементамиshouldComponentUpdate
(илиPureComponent
), чтобы предотвратить вторичный рендеринг, и дочерние элементы не могут быть визуализированы. Так что обратите на это внимание. На практике компоненты со «слотами», скорее всего, будут небольшими и быстро визуализируются, поэтому настройка производительности вряд ли потребуется.
Но если вы встретитеВ самом делеЕсли вам нужно настроить производительность компонента «слот», вы можете рассмотреть возможность извлечения части кода, производительность которой слишком низкая, поместить ее в отдельный компонент, а затем настроить.
Реакция в обучении иногда может быть болью - есть так много кодовых базов и инструментов! Хотите услышать мое мнение? Это игнорировать все эти кодовые основания и инструменты :) Если вы хотите пошаговое руководство, пожалуйста, прочитайте книгу, которую я написал -Pure React.
Если вы обнаружите ошибки в переводе или в других областях, требующих доработки, добро пожаловать наПрограмма перевода самородковВы также можете получить соответствующие бонусные баллы за доработку перевода и PR. начало статьиПостоянная ссылка на эту статьюЭто ссылка MarkDown этой статьи на GitHub.
Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из Интернета сНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,товар,дизайн,искусственный интеллектЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.