Пропсы React

В React Props (свойства) — это механизм передачи данных от родительского компонента к дочернему компоненту. Props доступны только для чтения; дочерние компоненты не могут напрямую изменять их. Вместо этого родительский компонент должен управлять ими и обновлять их.

Основное различие между state и props состоит в том, чтоprops. Props неизменяемы, тогда как state может изменяться в зависимости от действий пользователя. Именно поэтому некоторым контейнерным компонентам нужно определять state для обновления и изменения данных. Дочерние компоненты могут передавать данные только через props.


Использование props

Синтаксис передачи props:

<ComponentName propName={propValue} />

В следующем примере показано, как использовать props в компоненте:

Пример React

function HelloMessage(props) { return <h1>Hello {props.name}!</h1>; } const element = <HelloMessage name="Example"/>; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( element );

Попробуйте »

В примере атрибут name получается через props.name.


Props по умолчанию

Вы можете задать значения по умолчанию для props с помощью свойства defaultProps класса компонента, как показано в примере:

Пример React

class HelloMessage extends React.Component { render() { return ( <h1>Hello, {this.props.name}</h1> ); } } HelloMessage.defaultProps = { name: 'Example' }; const element = <HelloMessage/>; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( element );

Попробуйте »

Несколько props

Вы можете передать несколько свойств дочернему компоненту.

Пример

const UserCard = (props) => {
  return (
    <div>
      <h2>{props.name}</h2>
      <p>Возраст: {props.age}</p>
      <p>Местоположение: {props.location}</p>
    </div>
  );
};

const App = () => {
  return (
    <UserCard name="Alice" age={25} location="Нью-Йорк" />
  );
};

ReactDOM.render(<App />, document.getElementById('root'));

Валидация propTypes

propTypes — это инструмент, предоставляемый React для проверки типов пропсов компонента.

Вы можете использовать библиотеку prop-types для проверки типов пропсов компонентов.

В React propTypes определяется как статическое свойство компонента. Сначала вам нужно установить пакет prop-types:

npm install prop-types

Затем импортируйте prop-types в файл вашего компонента и определите свойство propTypes. Вот пример:

Пример

import PropTypes from 'prop-types';

const Greeting = (props) => {
  return <h1>Привет, {props.name}!</h1>;
};

Greeting.propTypes = {
  name: PropTypes.string.isRequired
};

const App = () => {
  return (
    <div>
      <Greeting name="Alice" />
      {/* <Greeting /> // Эта строка вызовет предупреждение в консоли, потому что name обязателен */}
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById('root'));

Передача функций обратного вызова в качестве props

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

Пример

class ParentComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { message: '' };
  }

  handleMessage = (msg) => {
    this.setState({ message: msg });
  };

  render() {
    return (
      <div>
        <ChildComponent onMessage={this.handleMessage} />
        <p>Сообщение от дочернего компонента: {this.state.message}</p>
      </div>
    );
  }
}

const ChildComponent = (props) => {
  const sendMessage = () => {
    props.onMessage('Привет от дочернего компонента!');
  };

  return (
    <div>
      <button onClick={sendMessage}>Отправить сообщение</button>
    </div>
  );
};

ReactDOM.render(<ParentComponent />, document.getElementById('root'));

Деструктуризация пропсов

В функциональных компонентах можно упростить код, деструктурируя props.

Пример

const Greeting = ({ name }) => {
  return <h1>Привет, {name}!</h1>;
};

const App = () => {
  return <Greeting name="Alice" />;
};

ReactDOM.render(<App />, document.getElementById('root'));

Итог

  • Передача и использование props: родительский компонент передает данные дочернему компоненту, а дочерний компонент черезpropsполучает.
  • Пропсы по умолчанию: ИспользуйтеdefaultPropsчтобы задать значения свойств компонента по умолчанию.
  • Проверка PropTypes: Используйтеprop-typesбиблиотеку для проверки типов пропсов.
  • Передача функций обратного вызова: Родительский компонент может передавать функции дочерним компонентам в качестве пропсов, чтобы обеспечить взаимодействие между компонентами.
  • Деструктуризация пропсов: Деструктурируйте пропсы в функциональных компонентах, чтобы упростить код.

Состояние и пропсы

В следующем примере показано, как использовать состояние и пропсы вместе в приложении. Мы можем задать состояние в родительском компоненте и передать его дочернему компоненту через пропсы на дочернем компоненте. В функции render мы задаём name и site, чтобы получить данные, переданные из родительского компонента.

Пример React

class WebSite extends React.Component { constructor() { super(); this.state = { name: "Example", site: "https://www.example.com" } } render() { return ( <div> <Name name={this.state.name} /> <Link site={this.state.site} /> </div> ); } } class Name extends React.Component { render() { return ( <h1>{this.props.name}</h1> ); } } class Link extends React.Component { render() { return ( <a href={this.props.site}> {this.props.site} </a> ); } } const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <WebSite /> );

Попробуйте »

Проверка Props

React.PropTypes, после React v15.5, был перемещён вprop-typesбиблиотеку.

<script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/prop-types/15.8.1/prop-types.min.js" type="application/javascript"></script>

Проверка props используетpropTypes, что гарантирует правильное использование компонентов нашего приложения. React.PropTypes предоставляет множество валидаторов для проверки корректности входящих данных. Когда в props передаются недопустимые данные, консоль JavaScript выдаст предупреждение.

В следующем примере создается компонент Mytitle. Свойство title является обязательным и должно быть строкой. Типы, не являющиеся строками, автоматически преобразуются в строки:

Пример React 16.4

var title = "Пример"; // var title = 123; class MyTitle extends React.Component { render() { return ( <h1>Hello, {this.props.title}</h1> ); } } MyTitle.propTypes = { title: PropTypes.string }; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <MyTitle title={title} /> );

Попробуйте »

Пример React 15.4

var title = "Пример"; // var title = 123; var MyTitle = React.createClass({ propTypes: { title: React.PropTypes.string.isRequired, }, render: function() { return <h1> {this.props.title} </h1>; } }); const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <MyTitle title={title} /> );

Попробуйте »

Конечно, мы можем рассмотреть большеPropTypesвалидаторов и как их использовать. Ниже приведены некоторые часто используемыеPropTypesописания валидаторов:

Базовые типы данных

  • PropTypes.string: Строка
  • PropTypes.number: Number
  • PropTypes.boolean: Boolean
  • PropTypes.object: Object
  • PropTypes.array: Массив
  • PropTypes.func: Function
  • PropTypes.symbol:Symbol

Специальные типы

  • PropTypes.node: Всё, что можно отрендерить: числа, строки, элементы или массивы (включая эти типы)
  • PropTypes.element: React-элемент
  • PropTypes.instanceOf(Class): Экземпляр класса

Комбинированные типы

  • PropTypes.oneOf(['option1', 'option2']): Тип enum, значение должно быть одним из предложенных вариантов
  • PropTypes.oneOfType([PropTypes.string, PropTypes.number]): Один из нескольких типов
  • PropTypes.arrayOf(PropTypes.number): Массив определённого типа
  • PropTypes.objectOf(PropTypes.number): Объект, состоящий из определённого типа
  • PropTypes.shape({ key: PropTypes.string, value: PropTypes.number }): Объект с определённой формой

Другие

  • PropTypes.any: Любой тип
  • PropTypes.exact({ key: PropTypes.string }): Объект с определёнными ключами и без лишних ключей

Ниже приведены примеры фрагментов кода, показывающие, как использовать различныеPropTypesvalidators:

Пример

import React from 'react';
import ReactDOM from 'react-dom/client';
import PropTypes from 'prop-types';

class MyComponent extends React.Component {
  static propTypes = {
    title: PropTypes.string.isRequired, // Должно быть строкой и обязательно
    age: PropTypes.number,              // Необязательное число
    isAdmin: PropTypes.bool,            // Необязательное логическое значение
    user: PropTypes.shape({             // Должен быть объектом с определённой структурой
      name: PropTypes.string,
      email: PropTypes.string
    }),
    items: PropTypes.arrayOf(PropTypes.string), // Должен быть массивом строк
    callback: PropTypes.func,           // Необязательная функция
    children: PropTypes.node,           // Необязательное содержимое для рендеринга
    options: PropTypes.oneOf(['option1', 'option2']), // Должно быть одним из конкретных значений
  };

  render() {
    return (
      <div>
        <h1>{this.props.title}</h1>
        {this.props.age && <p>Возраст: {this.props.age}</p>}
        {this.props.isAdmin && <p>Администратор</p>}
        {this.props.user && (
          <div>
            <p>Имя: {this.props.user.name}</p>
            <p>Эл. почта: {this.props.user.email}</p>
          </div>
        )}
        {this.props.items && (
          <ul>
            {this.props.items.map((item, index) => (
              <li key={index}>{item}</li>
            ))}
          </ul>
        )}
        {this.props.callback && (
          <button onClick={this.props.callback}>Нажми меня</button>
        )}
        {this.props.children}
        {this.props.options && <p>Option: {this.props.options}</p>}
      </div>
    );
  }
}

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <MyComponent
    title="Привет, мир!"
    age={30}
    isAdmin={true}
    user={{ name: "Иван Иванов", email: "[email protected]" }}
    items={['Элемент 1', 'Элемент 2', 'Элемент 3']}
    callback={() => alert('Кнопка нажата!')}
    options="option1"
  >
    <p>Это дочерний элемент</p>
  </MyComponent>
);
Другие расширения