Оригинальная ссылка:React Component Patterns
автор:Gustavo Matheus
По мере того, как React становится все более и более популярным в разработке интерфейсов, появляются различные шаблоны проектирования и новые концепции. Цель этой статьи — обобщить некоторые распространенные шаблоны проектирования при разработке React.
С сохранением состояния против без гражданства
Компоненты React могут быть с состоянием, которые могут манипулировать и изменять свое внутреннее состояние в течение своего жизненного цикла; Компоненты React также могут быть без состояния, которые только принимают реквизиты, переданные от родительского компонента, и отображают их.
Ниже приведеннет статусаизButton
Компонент, поведение которого полностью определяется реквизитами, переданными в:
const Button = props =>
<button onClick={props.onClick}>
{props.text}
</button>
Ниже приведенсостояниекомпонент (используя вышеуказанныйнет статусакомпоненты):
class ButtonCounter extends React.Component {
constructor() {
super();
this.state = { clicks: 0 };
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState({ clicks: ++this.state.clicks });
}
render() {
return (
<Button
onClick={this.handleClick}
text={`You've clicked me ${this.state.clicks} times !`}
/>
)
}
}
Как видите, вышеButtonCounter
компонент вstate
сохраняет собственное состояние вButton
Компоненты визуализируются только на основе реквизита. Эта разница может показаться небольшой, но без гражданстваButton
Компоненты очень многоразовые.
Контейнер против презентационных компонентов
При взаимодействии с внешними данными мы можем разделить компоненты на две категории:
- компонент контейнера: в основном отвечает за взаимодействие (общение) с внешними данными, такими какReduxи так далее для привязки данных и т.д.
- Компоненты дисплея: визуализирует на основе собственного состояния и свойств, полученных от родительского компонента, и не взаимодействует напрямую с внешними источниками данных.
давайте посмотрим на одинэкспонатКомпоненты:
const UserList = props =>
<ul>
{props.users.map(u => (
<li>{u.name} - {u.age} years old</li>
))}
</ul>
и этоэкспонатКомпоненты могут использоватьсяконтейнерОбновление компонентов:
class UserListContainer extends React.Component {
constructor() {
super()
this.state = { users: [] }
}
componentDidMount() {
fetchUsers(users => this.setState({ users }));
}
render() {
return <UserList users={this.state.users} />
}
}
Выделяя компоненты какконтейнеркомпоненты сэкспонатКомпонент, отделяющий сбор данных от рендеринга. Это также делаетUserList
Многоразовый. Если вы хотите узнать больше, вот некоторыеочень хорошая статья, очень доходчиво объяснил.
Компоненты высшего порядка
Компоненты высшего порядка (HOC) пригодятся, когда вы хотите повторно использовать логику компонента. Компонент высшего порядка — это функция JavaScript, которая принимает компонент React в качестве параметра и возвращает новый компонент.
Например: напишите компонент меню, который при нажатии на пункт меню разворачивает текущий пункт меню и отображает подменю. Конечно, мы можем контролировать состояние этого компонента меню в родительском компоненте, но более элегантный способ — использовать компонент более высокого порядка:
function makeToggleable(Clickable) {
return class extends React.Component {
constructor() {
super();
this.toggle = this.toggle.bind(this);
this.state = { show: false };
}
toggle() {
this.setState({ show: !this.state.show });
}
render() {
return (
<div>
<Clickable
{...this.props}
onClick={this.toggle}
/>
{this.state.show && this.props.children}
</div>
);
}
}
}
Таким образом, мы можем использовать синтаксис декоратора JavaScript, чтобы применить нашу логику кToggleableMenu
Компоненты:
@makeToggleable
class ToggleableMenu extends React.Component {
render() {
return (
<div onClick={this.props.onClick}>
<h1>{this.props.title}</h1>
</div>
);
}
}
Теперь мы можем поместить любое содержимое подменю вToggleableMenu
В компоненте:
class Menu extends React.Component {
render() {
return (
<div>
<ToggleableMenu title="First Menu">
<p>Some content</p>
</ToggleableMenu>
<ToggleableMenu title="Second Menu">
<p>Another content</p>
</ToggleableMenu>
<ToggleableMenu title="Third Menu">
<p>More content</p>
</ToggleableMenu>
</div>
);
}
}
когда вы используетеReduxизconnect
,илиReact RouterизwithRouter
функция, вы используете компонент более высокого порядка!
Рендеринг обратного вызова (рендеринг обратных вызовов)
Помимо компонентов высокого порядка,визуализировать обратный вызов— это еще один шаблон проектирования, делающий компоненты повторно используемыми.визуализировать обратный вызовЯдром компонента является дочерний компонент (или дочерний узел, т.е.props.children
), не кReact Component
предоставляется, но в виде функции обратного вызова. с вышеуказаннымHOCкомпонент в качестве примера, мы передаемоказыватьМетод обратного вызова переписывается следующим образом:
class Toggleable extends React.Component {
constructor() {
super();
this.toggle = this.toggle.bind(this);
this.state = { show: false }
}
toggle() {
this.setState({ show: !this.state.show });
}
render() {
return this.props.children(this.state.show, this.toggle)
}
}
Теперь мы можем передать функцию обратного вызова вToggleable
Компоненты как дочерние узлы. Реализуем предыдущий на новый ладHOCкомпонентыToggleableMenu
:
const ToggleableMenu = props => (
<Toggleable>
{(show, onClick) => (
<div>
<div onClick={onClick}>
<h1>{props.title}</h1>
</div>
{ show && props.children }
</div>
)}
</Toggleable>
)
И наш новыйMenu
Компонент реализован следующим образом:
class Menu extends React.Component {
render() {
return (
<div>
<ToggleableMenu title="First Menu">
<p>Some content</p>
</ToggleableMenu>
<ToggleableMenu title="Second Menu">
<p>Another content</p>
</ToggleableMenu>
<ToggleableMenu title="Third Menu">
<p>More content</p>
</ToggleableMenu>
</div>
);
}
}
да, вы правильно прочитали, новыйMenu
Компоненты те же, что и раньшеHOCВыкройка реализована точно так же!
В этой реализации мы преобразуем состояние внутри компонента (state
) удаляется из логики рендеринга компонента. В приведенном выше примере мы поместили логику рендеринга вToggleableMenu
извизуализировать обратный вызов, показывая при этом состояние компонента (state
) все ещеToggleable
техническое обслуживание внутри компонента.
понять больше
Некоторые из приведенных выше примеров — это лишь основы шаблонов проектирования React. Если вы хотите углубиться в тему шаблонов проектирования React, вот несколько действительно хороших учебных материалов, на которые стоит обратить внимание:
- React Component Patterns by Michael Chan
- React Patterns
- Presentational and Container Components
- React Higher Order Components in depth
- Function as Child Components
- Recompose
- Downshift
Обратите внимание на публичный аккаунт WeChat: KnownsecFED, получайте больше качественной галантереи по коду!