Inferno — высокопроизводительный фреймворк для построения интерфейсов на JavaScript, обеспечивающий виртуальный DOM и оптимизированное обновление пользовательского интерфейса. Одной из ключевых особенностей разработки на Inferno является работа с компонентами, а именно их композиция и наследование, что позволяет создавать гибкие и повторно используемые структуры интерфейса.
Компоненты в Inferno бывают двух типов:
Функциональные компоненты — простые функции,
принимающие props и возвращающие виртуальный DOM. Они не
имеют собственного состояния (до появления хуков) и являются идеальными
для отображения статических данных или чистых представлений.
Классовые компоненты — наследуются от
Inferno.Component и предоставляют доступ к жизненному
циклу, состоянию (state) и методам для управления
поведением компонента.
Пример классового компонента:
import { Component } from 'inferno';
class Button extends Component {
constructor(props) {
super(props);
this.state = { clicked: false };
}
handleClick = () => {
this.setState({ clicked: true });
}
render() {
return (
<button onCl ick={this.handleClick}>
{this.state.clicked ? 'Clicked' : 'Click me'}
</button>
);
}
}
Композиция заключается в том, что один компонент может включать в себя другие компоненты. Это основной способ повторного использования кода и построения сложного интерфейса из простых частей.
Ключевые моменты композиции:
props.props.children.Пример композиции:
const Card = ({ title, children }) => (
<div className="card">
<h2>{title}</h2>
<div className="card-content">{children}</div>
</div>
);
const App = () => (
<Card title="Пример карточки">
<p>Содержимое карточки</p>
</Card>
);
В этом примере компонент Card выступает контейнером для
произвольного содержимого, передаваемого через children.
Такой подход позволяет строить сложные интерфейсы, не создавая
монолитных компонентов.
Inferno поддерживает классическое наследование, позволяя создавать компоненты, расширяющие функциональность базового компонента. Наследование используется, когда требуется добавление специализированного поведения к общему компоненту без дублирования кода.
Пример наследования:
class BaseButton extends Component {
render() {
return <button>{this.props.label}</button>;
}
}
class ColoredButton extends BaseButton {
render() {
return <button style={{ color: this.props.color }}>{this.props.label}</button>;
}
}
В данном примере ColoredButton расширяет базовый
BaseButton, добавляя возможность задавать цвет текста через
props. При этом сохраняется исходная структура и поведение
базового компонента.
Рекомендации по наследованию:
componentDidMount,
componentDidUpdate) можно переопределять с вызовом
super, чтобы сохранить поведение родителя.Композиция и наследование тесно связаны с управлением состоянием:
Пример комбинированного подхода:
class Toggle extends Component {
constructor(props) {
super(props);
this.state = { on: false };
}
toggle = () => {
this.setState({ on: !this.state.on });
}
render() {
return this.props.render(this.state.on, this.toggle);
}
}
const App = () => (
<Toggle render={(on, toggle) => (
<button onCl ick={toggle}>
{on ? 'Включено' : 'Выключено'}
</button>
)}/>
);
Здесь компонент Toggle управляет состоянием, а через
композицию дочерний компонент отвечает только за отображение.
Inferno поддерживает подход Higher-Order Components (HOC), который позволяет создавать компоненты, оборачивающие другие компоненты для добавления функциональности.
Пример HOC:
const withLogger = (WrappedComponent) => {
return class extends Component {
componentDidMount() {
console.log('Компонент смонтирован');
}
render() {
return <WrappedComponent {...this.props} />;
}
};
};
const ButtonWithLogger = withLogger(Button);
Такой подход позволяет обогащать компоненты поведением без изменения их исходного кода, сохраняя принципы композиции и повторного использования.
props и
children.Эти методы дают возможность строить сложные интерфейсы в Inferno, сохраняя чистоту кода, повторное использование и управляемость состояния компонентов.