Вместо собственных велосипедов давайте использовать уже готовые подходы
Вместо собственных велосипедов давайте использовать уже готовые подходы
Начнём, на удивление, с самого простейшего вопроса: как отрендерить кусок в зависимости от проверки?
Как вы помните, Джсх это всё равно что Джс, поэтому в самом примитивном варианте просто вставьте ифы и ретёрны.
if (x) return <TruthyComp />;
// вернется если проверка на x
// не отработала в true
return <FalsyComp />;
Ну или тернарный оператор ?:
return x ? <TruthyComp /> : <FalsyComp />;
Что делать, если у вас большой компонент (не надо так) и нужно по условию отрендерить какой-то блок? Допустим, кнопку. Просто поместите проверку через оператор &&
в {}
.
function Mailbox(props) {
const unreadMessages = props.unreadMessages;
return (
<div>
<h1>Hello!</h1>
{unreadMessages.length > 0 && (
<h2>You have {unreadMessages.length} unread messages.</h2>
)}
</div>
);
}
Как замечено в официальной документации, такое возможно, потому что в Джаваскрипте выражение true && expression
выполнит expression
, а false && expression
выполнит false
.
Создаёте компонент вокруг другого компонента, передав ему какой-то набор пропов.
const Button = props =>
<button type="button" {...props}>
<Button />
// <button type="button"><button>
<Button className="CTA">Send Money</Button>
// <button type="button" class="CTA">Send Money</button>
Чилдрен может быть функцией. Знали?
class Auth extends React.Component {
state = {
isLoggedIn: false,
userId: 1
};
render() {
const { isLoggedIn, userId } = this.state;
return this.props.children({ isLoggedIn, userId });
}
}
function Lesson(props) {
return (
<View>
<h1>{props.title}</h1>
<Auth>
{function({ isLoggedIn, userId }) {
if (isLoggedIn) {
return props.lesson;
}
// возвращаем превью урока если человек не залогинен
return props.preview;
}}
</Auth>
</View>
);
}
Тот же самый паттерн используется в рендер пропе: просто вместо чилдрен используется проп render
и код выглядит как <Auth render={function() {...}} />
.
Ещё один способ передать пропы из одного компонента в другой: HoC.
HoC — это функция, в которую приходит компонент и которая возвращает другой компонент.
Из примеров: connect()
в react-redux и withRouter()
в Реакт-роутере.
function withAuth(Comp, options = {}) {
return class extends React.Component {
state = {
isLoggedIn: false,
userId: 1
};
render() {
const { isLoggedIn, userId } = this.state;
return <Comp isLoggedIn={isLoggedIn} userId={userId} />;
}
};
}
function Lesson(props) {
return (
<View>
<h1>{props.title}</h1>
{this.props.isLoggedIn ? props.lesson : props.preview}
</View>
);
}
const LessonWithAuth = withAuth(Lesson);
В чём отличие от рендер пропа? В том, что менее явное поведение: в рендер пропе обычная функция с набором аргументов, а тут в пропы нашего компонента спускаются неизвестные пропы.
Здесь оставлю ссылку на пост Юли, которая проходила курс: она расписала модели «родитель → ребенок», «ребенок → родитель» и «ребенок → ребенок».
Паттерны нужны, чтобы не плодить свои велосипеды и не усложнять себе (и другим разработчикам!) жизнь.
Используйте всё кроме HoC — за лаконичность их АПИ расплачиваетесь неочевидностью пропов.