В предыдущей статье мы объяснили, как шаблоны проектирования могут помочь контролировать кодовую базу и поддерживать масштабируемость приложений React.js. Мы выделили некоторые популярные шаблоны проектирования для React.js. Затем мы сосредоточимся на HOC и предоставим пример того, как создать простой HOC, а затем рассмотрим реальные сценарии использования HOC для добавления функций аутентификации или извлечения данных в компонент.
Итак, приготовьте свой любимый напиток «если вы инженер, то это, скорее всего, кофе ☕️», и давайте погрузимся во второй шаблон проектирования React.js, а именно Render Props.
Введение:
Представьте, что вы создаете приложение React, которое отображает список статей. Каждая статья имеет заголовок, краткое содержание и ссылку «Подробнее». Вы хотите убедиться, что список статей можно использовать повторно и его можно использовать в разных частях вашего приложения.
Одним из подходов к решению этой проблемы является создание повторно используемого компонента ArticleList
, который принимает массив статей в качестве реквизита и отображает их с помощью функции map
. Однако что, если вы также хотите иметь возможность настраивать способ отображения каждой статьи? Например, вы можете изменить макет, добавить дополнительный контент или применить разные стили к каждой статье.
Здесь пригодится шаблон Render Props.
Шаблон рендеринга реквизита:
Не пугайтесь красивого названия, на самом деле оно довольно простое. Паттерн Render Props — это способ совместного использования кода между компонентами в React. Он включает в себя передачу функции в качестве реквизита дочернему компоненту, который затем использует эту функцию для отображения своего содержимого. Просто не правда ли 🙂
По соглашению функция обычно называется «реквизитом рендеринга», потому что она отвечает за рендеринг содержимого дочернего компонента. Родительский компонент предоставляет свойство рендеринга, а дочерний компонент вызывает его для рендеринга своего содержимого.
Давайте погрузимся в пример, которого мы все ждали 😬
Мы начнем с создания повторно используемого компонента Article
, который принимает объект статьи в качестве реквизита и отображает его.
const Article = ({ article }) => { const { title, summary, url } = article; return ( <div className="article"> <h2>{title}</h2> <p>{summary}</p> <a href={url} className="read-more"> Read more </a> </div> ); };
Далее мы создадим наш компонент ArticleList
. Вместо рендеринга статей напрямую мы будем использовать свойство рендеринга под названием renderArticle
для рендеринга каждой статьи. Функция renderArticle
принимает объект статьи в качестве параметра и возвращает элемент React, представляющий обработанную статью.
const ArticleList = ({ articles, renderArticle }) => { return ( <div className="article-list"> {articles.map((article, index) => ( renderArticle(article, index) ))} </div> ); };
Теперь мы можем использовать компонент ArticleList
в нашем приложении. Мы можем передать массив статей и функцию renderArticle
, которая отображает каждую статью по-своему.
const App = () => { const articles = [ { title: "React Hooks", summary: "Learn how to use React Hooks", url: "https://reactjs.org/docs/hooks-intro.html", }, { title: "Render Props", summary: "Learn how to use Render Props", url: "https://reactjs.org/docs/render-props.html", }, ]; const renderArticle = (article) => { return <Article article={article} />; } return ( // pass articles and renderArticle as props to ArticleList <ArticleList articles={articles} renderArticle={renderArticle} /> ); };
В этом примере мы передали функцию renderArticle
, которая просто отображает компонент Article
для каждой статьи. Однако мы могли бы также передать другую функцию renderArticle
, которая отображает статьи по-другому. Довольно круто, да? 😎
Расширение функционала:
Допустим, мы хотим отображать каждую статью с другим цветом фона в зависимости от ее индекса. Мы можем изменить нашу функцию renderArticle
, чтобы она принимала дополнительный параметр index
и применяла к статье другой цвет фона на основе индекса.
const renderArticle = (article, index) => { // apply different background color based on index const backgroundColor = index % 2 === 0 ? "#f2f2f2" : "#ffffff"; return ( <div style={{ backgroundColor }} key={article.title}> <Article article={article} /> </div> ); };
В этом примере мы вычисляем цвет фона на основе индекса статьи. Если индекс четный, мы используем светло-серый цвет (#f2f2f2
), а если индекс нечетный, мы используем белый (#ffffff
). Мы также установили реквизит key
для внешнего элемента div
, чтобы помочь React идентифицировать каждый элемент статьи в списке.
Теперь мы можем передать эту функцию renderArticle
нашему компоненту ArticleList
, и он будет отображать каждую статью с другим цветом фона в зависимости от ее индекса.
const App = () => { const articles = [ { title: "React Hooks", summary: "Learn how to use React Hooks", url: "https://reactjs.org/docs/hooks-intro.html", }, { title: "Render Props", summary: "Learn how to use Render Props", url: "https://reactjs.org/docs/render-props.html", }, ]; const renderArticle = (article, index) => { // apply different background color based on index const backgroundColor = index % 2 === 0 ? "#f2f2f2" : "#ffffff"; return ( <div style={{ backgroundColor }} key={article.title}> <Article article={article} /> </div> ); } return ( // pass articles and renderArticle as props to ArticleList <ArticleList articles={articles} renderArticle={renderArticle} /> ); };
Это всего лишь один пример того, как мы можем использовать шаблон Render Props для настройки рендеринга компонента. Передавая функцию рендеринга в качестве реквизита, мы можем сделать наши компоненты более пригодными для повторного использования и гибкими, а также позволить настраивать их по-разному в разных частях нашего приложения.
Преимущества и недостатки использования шаблона Render Props:
Шаблон Render Props в React.js может быть мощным инструментом, но, как и у любого другого инструмента, у него есть свои плюсы и минусы.
Преимущества:
- Повторное использование: шаблон Render Props позволяет вам повторно использовать одну и ту же логику компонента в нескольких компонентах, делая ваш код более СУХИМ (не повторяйте себя) и проще в обслуживании.
- Гибкость: передавая функцию в качестве реквизита, вы можете настроить поведение компонента в зависимости от потребностей родительского компонента.
- Инкапсуляция: шаблон Render Props позволяет вам инкапсулировать логику компонента и предоставлять родительскому компоненту только то, что необходимо.
Недостатки:
- Детализация реквизита: когда вы передаете функцию в качестве реквизита дочернему компоненту, вы можете получить несколько уровней вложенности, что приведет к сверлению реквизита и усложнит чтение и обслуживание вашего кода.
- Сложность: шаблон Render Props может привести к сложному коду, что затрудняет понимание и поддержку разработчиками.
- Чрезмерное использование: то, что вы можете использовать шаблон Render Props, не означает, что вы должны это делать. Чрезмерное использование этого шаблона может затруднить чтение и понимание вашего кода, поэтому важно использовать его разумно.
Понимая эти преимущества и недостатки, вы можете принимать обоснованные решения о том, когда и как использовать шаблон в своем коде. И всегда помните, с большой силой приходит большая ответственность.
Заключение:
Теперь вы знаете, как использовать Render Props.
Чтобы настроить компоненты, нет остановок!
Шаблон Render Props прост в использовании,
Он делает ваш код чистым и свободным.
Компоненты многократного использования, настраиваемые настолько, насколько это возможно.
Масштабируемость вашего приложения React очевидна.
Передать функцию — это несложно.
С помощью Render Props ваш код готов.
Если вам понравилась эта статья о React,
следите за новостями, они не прекратятся!
Ознакомьтесь также с нашими предыдущими,
чтобы повысить свой React IQ!
От хуков до состояния и компонентов тоже,
Наши статьи о React обязательно вас заинтересуют!
Так что продолжайте учиться и продолжайте писать код,
И ваши навыки работы с React будут продолжать расти!
Если вы достигли этого момента «и вам понравилось рифмованное заключение 😬», рассмотрите возможность поаплодировать 👏 и подписаться на мой аккаунт, чтобы в будущем получать больше подобного контента.