Освоение реквизитов и типов реквизитов в React
Опубликовано: 2022-03-10Вас смущают props и PropTypes? Ты не один. Я собираюсь провести вас через все, что касается реквизита и типов реквизита. Они могут значительно облегчить вашу жизнь при разработке приложений React. Это руководство познакомит вас с деталями реквизитов, передачей и доступом к реквизитам, а также передачей информации любому компоненту с использованием реквизитов.
Создание приложений React включает в себя разбиение пользовательского интерфейса на несколько компонентов, что означает, что нам нужно будет передавать данные из одного компонента в другой. Реквизиты — это важный механизм для передачи информации между компонентами React, и мы рассмотрим их очень подробно. Эта статья была бы неполной без рассмотрения PropTypes, потому что они гарантируют, что компоненты используют правильный тип данных и передают правильные данные.
Всегда рекомендуется проверять данные, которые мы получаем в качестве реквизита, с помощью PropTypes. Вы также узнаете об интеграции PropTypes в React, проверке типов с помощью PropTypes и использовании defaultProps. В конце этого урока вы поймете, как эффективно использовать свойства и типы свойств. Важно, чтобы у вас уже были базовые знания о том, как работает React.
Понимание реквизита
React позволяет нам передавать информацию компонентам, используя вещи, называемые реквизитами (сокращение от свойств). Поскольку React состоит из нескольких компонентов, пропсы позволяют обмениваться одними и теми же данными между компонентами, которым они нужны. Он использует однонаправленный поток данных (компоненты «родитель-потомок»). Однако с помощью функции обратного вызова можно передать свойства обратно от дочернего компонента к родительскому.
Эти данные могут быть в разных формах: числа, строки, массивы, функции, объекты и т. д. Мы можем передавать реквизиты любому компоненту так же, как мы можем объявлять атрибуты в любом HTML-теге. Взгляните на код ниже:
<PostList posts={postsList} />
В этом фрагменте мы передаем свойство с именем posts
компоненту с именем PostList
. Этот реквизит имеет значение {postsList}
. Давайте разберемся, как получить доступ и передать данные.
Передача и доступ к свойствам
Чтобы сделать этот урок интересным, давайте создадим приложение, которое показывает список имен и сообщений пользователей. Демонстрация приложения показана ниже:
Приложение состоит из набора компонентов: компонента App
, компонента PostList
и компонента Post
.
Для списка сообщений потребуются такие данные, как content
и name
пользователя. Мы можем построить данные следующим образом:
const postsList = [ { id: 1, content: "The world will be out of the pandemic soon", user: "Lola Lilly", }, { id: 2, content: "I'm really exited I'm getting married soon", user: "Rebecca Smith", }, { id: 3, content: "What is your take on this pandemic", user: "John Doe", }, { id: 4, content: "Is the world really coming to an end", user: "David Mark", }, ];
После этого нам нужен компонент App
для извлечения данных. Вот базовая структура этого компонента:
const App = () => { return ( <div> <PostList posts={postsList} /> </div> ); };
Здесь мы передаем массив сообщений в качестве реквизита для PostList
(который мы создадим чуть позже). Родительский компонент, PostList
, получит доступ к данным в postsList
, которые будут переданы в качестве реквизита posts
дочернему компоненту ( Post
). Если вы помните, наше приложение состоит из трех компонентов, которые мы создадим по ходу работы.
Давайте создадим PostList
:
class PostList extends React.Component { render() { return ( <React.Fragment> <h1>Latest Users Posts</h1> <ul> {this.props.posts.map((post) => { return ( <li key={post.id}> <Post {...post} /> </li> ); })} </ul> </React.Fragment> ); } }
Компонент PostList
будет получать posts
в качестве своей опоры. Затем он будет перебирать реквизит posts
, this.props.posts
, чтобы возвращать каждый опубликованный элемент в виде компонента Post
(который мы смоделируем позже). Также обратите внимание на использование key
в приведенном выше фрагменте. Для новичков в React ключ — это уникальный идентификатор, назначаемый каждому элементу в нашем списке, что позволяет нам различать элементы. В данном случае ключом является id
каждого поста. У двух элементов не может быть одинаковых id
, поэтому для этой цели можно использовать хороший фрагмент данных.
Между тем, остальные свойства передаются в качестве реквизита компоненту Post
( <Post {...post} />
).
Итак, давайте создадим компонент Post
и воспользуемся реквизитами в нем:
const Post = (props) => { return ( <div> <h2>{props.content}</h2> <h4>username: {props.user}</h4> </div> ); };
Мы создаем компонент Post
как функциональный компонент, а не определяем его как компонент класса, как мы сделали для компонента PostList
. Я сделал это, чтобы показать вам, как получить доступ к свойствам в функциональном компоненте по сравнению с тем, как мы получаем к ним доступ в компоненте класса с помощью this.props
. Поскольку это функциональный компонент, мы можем получить доступ к значениям с помощью props
.
Теперь мы узнали, как передавать реквизиты и получать к ним доступ, а также как передавать информацию от одного компонента к другому. Давайте теперь рассмотрим, как свойства работают с функциями.
Передача функций через свойства
В предыдущем разделе мы передавали массив данных в качестве свойств от одного компонента к другому. Но что, если вместо этого мы работаем с функциями? React позволяет нам передавать функции между компонентами. Это удобно, когда мы хотим инициировать изменение состояния родительского компонента из его дочернего компонента. Реквизит должен быть неизменным; вы не должны пытаться изменить значение реквизита. Вы должны сделать это в компоненте, который передает его вниз, который является родительским компонентом.
Давайте создадим простое демонстрационное приложение, которое прослушивает событие щелчка и изменяет состояние приложения. Чтобы изменить состояние приложения в другом компоненте, мы должны передать нашу функцию компоненту, состояние которого нужно изменить. Таким образом, у нас будет функция в нашем дочернем компоненте, способная изменять состояние.
Звучит немного сложно? Я создал простое приложение React, которое меняет состояние одним нажатием кнопки и отображает приветственную информацию:
В приведенной выше демонстрации у нас есть два компонента. Одним из них является компонент App
, который является родительским компонентом, содержащим состояние приложения и функцию для установки состояния. ChildComponent
будет дочерним элементом в этом сценарии, и его задача — отображать приветственную информацию при изменении состояния.
Разобьем это на код:
class App extends React.Component { constructor(props) { super(props); this.state = { isShow: true, }; } toggleShow = () => { this.setState((state) => ({ isShow: !state.isShow })); }; render() { return ( <div> <ChildComponent isShow={this.state.isShow} clickMe={this.toggleShow} /> </div> ); } }
Обратите внимание, что мы установили для нашего состояния значение true
, а метод для изменения состояния создан в компоненте App
. В функции render()
мы передаем состояние приложения в качестве isShow
ChildComponent
компоненту ChildComponent. Мы также передаем функцию toggleShow()
как реквизит с именем clickMe
.
Мы будем использовать это в ChildComponent
, который выглядит так:
class ChildComponent extends React.Component { clickMe = () => { this.props.clickMe(); }; render() { const greeting = "Welcome to React Props"; return ( <div style={{ textAlign: "center", marginTop: "8rem" }}> {this.props.isShow ? ( <h1 style={{ color: "green", fontSize: "4rem" }}>{greeting}</h1> ) : null} <button onClick={this.clickMe}> <h3>click Me</h3> </button> </div> ); } }
Самое важное, что было сказано выше, это то, что компонент App
передает функцию в качестве реквизита для ChildComponent
. Функция clickMe()
используется для обработчика кликов в ChildComponent
, тогда как ChildComponent
не знает логики функции — он запускает функцию только при нажатии кнопки. Состояние изменяется при вызове функции, и как только состояние изменилось, состояние снова передается как свойство. Все затронутые компоненты, такие как дочерний элемент в нашем случае, будут отображаться снова.
Мы должны передать состояние приложения, isShow
, в качестве реквизита для ChildComponent
, потому что без него мы не можем написать приведенную выше логику для отображения greeting
при обновлении состояния.
Теперь, когда мы рассмотрели функции, давайте обратимся к проверке. Всегда рекомендуется проверять данные, которые мы получаем через реквизиты, с помощью PropTypes. Давайте погрузимся в это сейчас.
Что такое PropTypes в React?
PropTypes — это механизм, гарантирующий, что компоненты используют правильный тип данных и передают правильные данные, и что компоненты используют правильный тип реквизита, и что принимающие компоненты получают правильный тип реквизита.
Мы можем думать об этом как о доставке щенка в зоомагазин. Зоомагазину не нужны свиньи, львы, лягушки или гекконы — ему нужны щенки. PropTypes гарантирует, что в зоомагазин будет доставлен правильный тип данных (щенок), а не какое-то другое животное.
В разделе выше мы увидели, как передавать информацию любому компоненту с помощью свойств. Мы передавали реквизиты непосредственно компоненту в качестве атрибута, а также передавали реквизиты извне компонента и использовали их в этом компоненте. Но мы не проверяли, какой тип значений мы получаем в нашем компоненте через реквизиты или что все еще работает.
Это полностью зависит от нас, проверять ли данные, которые мы получаем в компоненте через реквизиты. Но в сложном приложении всегда рекомендуется проверять эти данные.
Использование PropTypes
Чтобы использовать PropTypes, мы должны добавить пакет в качестве зависимости к нашему приложению через npm или Yarn, выполнив следующий код в командной строке. Для нпм:
npm install --save prop-types
И для пряжи:
yarn add prop-types
Чтобы использовать PropTypes, нам сначала нужно импортировать PropTypes из пакета prop-types:
import PropTypes from 'prop-types';
Давайте используем ProTypes в нашем приложении, в котором перечислены сообщения пользователей. Вот как мы будем использовать его для компонента Post
:
Post.proptypes = { id: PropTypes.number, content: PropTypes.string, user: PropTypes.string }
Здесь PropTypes.string
и PropTypes.number
являются валидаторами свойств, которые можно использовать, чтобы убедиться, что полученные свойства имеют правильный тип. В приведенном выше коде мы объявляем id
числом, а content
и user
— строками.
Кроме того, PropTypes полезны для отлова ошибок. И мы можем принудительно передавать реквизиты, используя isRequired
:
Post.proptypes = { id: PropTypes.number.isRequired, content: PropTypes.string.isRequired, user: PropTypes.string.isRequired }
У PropTypes много валидаторов. Вот некоторые из наиболее распространенных:
Component.proptypes = { stringProp: PropTypes.string, // The prop should be a string numberProp: PropTypes.number, // The prop should be a number anyProp: PropTypes.any, // The prop can be of any data type booleanProp: PropTypes.bool, // The prop should be a function functionProp: PropTypes.func // The prop should be a function arrayProp: PropTypes.array // The prop should be an array }
Доступно больше типов, которые вы можете проверить в документации React].
Реквизит по умолчанию
Если мы хотим передать некоторую информацию по умолчанию нашим компонентам с помощью свойств, React позволяет нам сделать это с помощью чего-то, что называется defaultProps
. В случаях, когда PropTypes являются необязательными (то есть они не используют isRequired
), мы можем установить defaultProps
. Реквизиты по умолчанию гарантируют, что реквизиты имеют значение на случай, если ничего не будет передано. Вот пример:
Class Profile extends React.Component{ // Specifies the default values for props static defaultProps = { name: 'Stranger' }; // Renders "Welcome, Stranger": render() { return <h2> Welcome, {this.props.name}<h2> } }
Здесь будет использоваться defaultProps
, чтобы убедиться, что this.props.name
имеет значение, если оно не указано родительским компонентом. Если классу Profile
не передано имя, то он будет иметь свойство по умолчанию Stranger
, на которое можно будет вернуться. Это предотвращает любую ошибку, когда никакая опора не передается. Я советую вам всегда использовать defaultProps
для каждого необязательного PropType.
Заключение
Надеюсь, вам понравилось работать с этим уроком. Надеюсь, это показало вам, насколько важны props и propTypes для создания приложений React, потому что без них мы не смогли бы передавать данные между компонентами, когда происходит взаимодействие. Они являются основной частью управляемой компонентами архитектуры управления состоянием, вокруг которой разработан React.
PropTypes — это бонус за то, что компоненты используют правильный тип данных и передают правильные данные, и что компоненты используют правильный тип реквизита, и что принимающие компоненты получают правильный тип реквизита.
Если у вас есть какие-либо вопросы, вы можете оставить их в разделе комментариев ниже, и я буду рад ответить на каждый из них и решить любые проблемы с вами.
использованная литература
- «Мышление в React», React Docs
- «Список и ключи», React Docs
- «Проверка типов с помощью PropTypes», React Docs
- «Как передать свойства компонентам в React», Робин Вирух