157 lines
8.6 KiB
Markdown
157 lines
8.6 KiB
Markdown
|
---
|
|||
|
title: React Props and State
|
|||
|
localeTitle: Реактивы и государство
|
|||
|
---
|
|||
|
## Опоры и государство
|
|||
|
|
|||
|
Существует два типа данных, которые управляют компонентом: реквизитом и состоянием. Реквизит устанавливается родителем, и они фиксируются на протяжении всего жизненного цикла компонента. Для данных, которые будут меняться, мы должны использовать состояние.
|
|||
|
|
|||
|
### Реквизит
|
|||
|
|
|||
|
Большинство компонентов могут быть настроены с различными параметрами при их создании. Эти параметры создания называются `props` .
|
|||
|
|
|||
|
Ваши собственные компоненты также могут использовать реквизиты. Это позволяет вам создать один компонент, который используется во многих разных местах вашего приложения, с немного разными свойствами в каждом месте. См. `this.props` в вашей функции рендеринга:
|
|||
|
```
|
|||
|
class Welcome extends React.Component {
|
|||
|
render() {
|
|||
|
return <h1>Hello {this.props.name}</h1>;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
const element = <Welcome name="neel" />;
|
|||
|
```
|
|||
|
|
|||
|
Строка `<Welcome name="neel" />` создает имя свойства со значением `"neel"` .
|
|||
|
|
|||
|
свойство передается компоненту, подобно тому, как передается аргумент функции. Фактически, мы могли бы даже переписать компонент, чтобы быть проще:
|
|||
|
```
|
|||
|
function Welcome(props) {
|
|||
|
return <h1>Hello {props.name}</h1>;
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
Мы можем сделать свойство name необязательным, добавив defaultProps в класс приветствия:
|
|||
|
```
|
|||
|
class Welcome extends React.Component {
|
|||
|
render() {
|
|||
|
return <h1>Hello {this.props.name}</h1>;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
Welcome.defaultProps = {
|
|||
|
name: "world",
|
|||
|
};
|
|||
|
```
|
|||
|
|
|||
|
Если Welcome вызывается без имени, он просто отображает `<h1> Hello world</h1>` .
|
|||
|
|
|||
|
Таким образом, `props` может исходить от родителя или может быть установлен самим компонентом.
|
|||
|
|
|||
|
Раньше вы меняли реквизит с помощью setProps и replaceProps, но они **устарели** . Во время жизненного цикла компонента реквизит не должен меняться (считайте его неизменным).
|
|||
|
|
|||
|
Поскольку реквизиты передаются, и они не могут измениться, вы можете подумать о любом компоненте React, который использует только реквизит (и не состояние) как «чистый», то есть он всегда будет отображать один и тот же результат с одним и тем же входом. Это делает их очень простыми для тестирования.
|
|||
|
|
|||
|
### состояние
|
|||
|
|
|||
|
Как и `props` , `state` хранит информацию о компоненте. Однако вид информации и то, как она обрабатывается, различна.
|
|||
|
|
|||
|
По умолчанию компонент не имеет состояния. Компонент `Welcome` сверху является апатридом:
|
|||
|
```
|
|||
|
function Welcome(props) {
|
|||
|
return <h1>Hello {props.name}</h1>;
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
Когда компонент должен отслеживать информацию между визуализациями, сам компонент может создавать, обновлять и использовать состояние.
|
|||
|
|
|||
|
Мы будем работать с довольно простым компонентом, чтобы увидеть, как `state` работает в действии. У нас есть кнопка, которая отслеживает, сколько раз вы ее нажали.
|
|||
|
|
|||
|
вот код:
|
|||
|
```
|
|||
|
class Button extends React.Component {
|
|||
|
constructor() {
|
|||
|
super();
|
|||
|
this.state = {
|
|||
|
count: 0,
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
updateCount() {
|
|||
|
this.setState((prevState, props) => {
|
|||
|
return { count: prevState.count + 1 }
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
render() {
|
|||
|
return (<button
|
|||
|
onClick={() => this.updateCount()}
|
|||
|
>
|
|||
|
Clicked {this.state.count} times
|
|||
|
</button>);
|
|||
|
}
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
### состояние создается в компоненте
|
|||
|
|
|||
|
Давайте посмотрим на метод `constructor` :
|
|||
|
```
|
|||
|
constructor() {
|
|||
|
super();
|
|||
|
this.state = {
|
|||
|
count: 0,
|
|||
|
};
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
Здесь состояние получает исходные данные. Исходные данные могут быть жестко закодированы (как указано выше), но могут также поступать из `props` .
|
|||
|
|
|||
|
### `state` изменчиво
|
|||
|
|
|||
|
Вот метод `updateCount` :
|
|||
|
```
|
|||
|
updateCount() {
|
|||
|
this.setState((prevState, props) => {
|
|||
|
return { count: prevState.count + 1 }
|
|||
|
});
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
Мы меняем состояние, чтобы отслеживать общее количество кликов. Важным битом является setState. Во-первых, обратите внимание, что setState принимает функцию, потому что setState может запускаться асинхронно. Он должен принимать функцию обратного вызова, а не напрямую обновлять состояние. Вы можете видеть, что у нас есть доступ к prevState в обратном вызове, это будет содержать предыдущее состояние, даже если состояние уже обновлено где-то в другом месте.
|
|||
|
|
|||
|
Реакция идет на один шаг лучше, setState обновляет объект `state` **и** автоматически ретранслирует компонент.
|
|||
|
|
|||
|
### предупреждения о `state`
|
|||
|
|
|||
|
> Заманчиво написать `this.state.count = this.state.count + 1` .
|
|||
|
|
|||
|
**Не делайте этого.** React не может прослушать состояние, которое будет обновляться таким образом, поэтому ваш компонент не будет повторно отображать. Всегда используйте `setState` .
|
|||
|
|
|||
|
Также может возникнуть соблазн написать что-то вроде этого:
|
|||
|
```
|
|||
|
// DO NOT USE
|
|||
|
this.setState({
|
|||
|
count: this.state.count + 1
|
|||
|
});
|
|||
|
```
|
|||
|
|
|||
|
Хотя это может показаться разумным, оно не вызывает ошибок, и вы можете найти примеры, которые используют этот синтаксис в Интернете, это неправильно. Это не учитывает асинхронный характер, который может использовать `setState` и может вызывать ошибки с отсутствием данных состояния синхронизации.
|
|||
|
|
|||
|
### Программа продолжается !!!
|
|||
|
|
|||
|
И , наконец, `render`
|
|||
|
```
|
|||
|
render() {
|
|||
|
return (<button
|
|||
|
onClick={() => this.updateCount()}
|
|||
|
>
|
|||
|
Clicked {this.state.count} times
|
|||
|
</button>);
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
`onClick={() => this.updateCount()}` означает, что при нажатии кнопки будет вызываться метод updateCount. Нам нужно использовать **функцию со стрелкой** ES6, так что updateCount будет иметь доступ к состоянию этого экземпляра.
|
|||
|
|
|||
|
Текст, отображаемый на кнопке, - это `Clicked {this.state.count} times` , который будет использовать то, что this.state.count находится во время рендеринга.
|
|||
|
|
|||
|
Дополнительная информация о: [**Реагирует реквизит и состояние**](https://facebook.github.io/react-vr/docs/components-props-and-state.html)
|