React patterns

Stateless function

Stateless function - отличный способ определить компоненты с высокой степенью многократного использования. Они не имеют собственное состояние; они просто функции.

Hi there!

Им передаются props.

Hi John!

Они могут определять локальные переменные, где используется функциональный блок.

John

JSX spread attributes

JSX spread attributes - это функция JSX. Это синтаксический сахар для передачи всех свойств объекта как атрибутов JSX.

Эти два примера эквивалентны.

// props written as attributes
<main className="main" role="main">{children}</main>
// props "spread" from object
<main {...{className: "main", role: "main", children}} />

Используйте это для пересылки свойств в более глубокий компоненты.

const MyDiv = (props) => <div className="myDiv" {...props} />;

Теперь мы можем ожидать, что MyDiv добавит атрибуты, к которым он относится, а также к тем, к которым он не относится.

Hello my custom div
important

Имейте в виду, что порядок имеет значение. Если props.className определен, он перепишет className, определенный MyDiv

<MyDiv className="custom-className" />
// output: <div className="custom-className"></div>

Мы можем сделать так, чтобы MyDiv className всегда «выигрывал», поместив его после свойств распространения ({... props}).

const MyDiv = (props) => <div {...props} className="my-div" />;

Или же мы можем обьединить базовый className компонента кастомным приходящим из props.className

const MyDiv = ({ className, ...props }) => (
<div className={["my-div", className].join(" ")} {...props} />
);

Destructuring arguments

Деструктуризация - это особенность ES2015.

Он прекрасно сочетается с props в Stateless функциях.

Эти примеры эквивалентны.

const Greeting = (props) => <div>Hi {props.name}!</div>;
const Greeting = ({ name }) => <div>Hi {name}!</div>;

Rest operator (...) позволяет собрать все оставшиеся свойства в новом объекте.

const Greeting = ({ name, ...props }) => <div>Hi {name}!</div>;

В свою очередь, этот объект может использовать JSX Spread для пересылки свойств в составной компонент.

const Greeting = ({ name, ...props }) => <div {...props}>Hi {name}!</div>;
warning

Избегайте пересылки props, отличных от DOM, на составные компоненты. Деструктуризация упрощает это, потому что вы можете создать новый объект props без свойств, специфичных для компонента.

Conditional rendering

note

Вы не можете использовать обычные условия if / else внутри определения компонента. Условный (тернарный) оператор - ваш друг.

IF

{
condition && <span>Rendered when `truthy`</span>;
}

UNLESS

{
condition || <span>Rendered when `falsey`</span>;
}

IF-ELSE (небольшой блок)

{
condition ? (
<span>Rendered when `truthy`</span>
) : (
<span>Rendered when `falsey`</span>
);
}

IF-ELSE (большой блок)

{
condition ? (
<span>Rendered when `truthy`</span>
) : (
<span>Rendered when `falsey`</span>
);
}

Render callback

Использование функции в качестве children по своей сути бесполезно.

<div>{() => { return "hello world!"}()}</div>

Однако его можно использовать при создании компонентов для серьезных целей. Этот метод обычно называют render callbacks.

При применении логика рендеринга может храниться в компоненте владельца, а не делегироваться.

Вот компонент, который использует обратный вызов Render.

Это бесполезно, но для начала это простая иллюстрация.

const Width = ({ children }) => children(500);

Компонент вызывает children как функцию с некоторым количеством аргументов. Вот это число 500

Чтобы использовать этот компонент, мы даем ему функцию как дочерний элемент.

window is 500

При такой настройке мы можем использовать эту ширину для принятия решений о рендеринге.

<Width>
{(width) => (width > 600 ? <div>min-width requirement met!</div> : null)}
</Width>

Если мы планируем часто использовать это условие, мы можем определить другие компоненты для инкапсуляции повторно используемой логики.

Visible

Очевидно, что компонент static Width бесполезен, но есть компонент, который следит за окном браузера.

Вот пример реализации. Resizer Component

Window width is 200

Теперь если вы попробуете изменить размер окна вы увидите актуальную ширину екрана.

Higher-order component

Функция высшего порядка (HOC) - это функция, которая принимает и / или возвращает функцию. Итак, что такое компонент высшего порядка?

Если вы уже используете компоненты контейнера, это просто общие контейнеры, заключенные в функцию.

Начнем с нашего stateless компонента <Greeting/>.

Connecting...
Hi John!

Если он получит props.name, он отобразит эти данные. В противном случае он скажет, что это «Connecting...». Теперь о функции высшего порядка.

const withName = (ComposedComponent) =>
class extends React.Component {
constructor() {
super();
this.state = { name: "" };
}
componentDidMount() {
// this would fetch or connect to a store
this.setState({ name: "Michael" });
}
render() {
return <ComposedComponent {...this.props} name={this.state.name} />;
}
};

Это просто функция, которая возвращает компонент, который отображает компонент, который мы передали в качестве аргумента.

На последнем этапе нам нужно обернуть ваш компонент Greeting в Connect.

const ConnectedMyComponent = withName(Greeting);

Это мощный шаблон для обеспечения выборки и предоставления данных любому количеству stateless компонентов.

Edit this page on GitHub