Руководство ReactJS props и state
1. Подсказка
В данной статье я объясню принцип "props" и "state" в React. И так же сравню отличие между "props" и "state".
Если вы начинающий с React, вам стоит изучить первый урок про React по следующей ссылке, он поможет вам создать среду для React и успешно запустить пример "Hello React".
2. ReactJS props
"props" это аббревиатура "properties", но является принципом в ReactJS. На самом деле props является объектом, он хранит значения attribute (атрибутов) одного тега (Tag).

Нам нужно разъяснить принцип props с помощью примеров.
OK, первый пример, в одной папке, создайте 2 файла props-example.jsx & props-example.html.
props-example.jsx
// Create a ES6 class component
class Greeting extends React.Component {
// Use the render function to return JSX component
render() {
return (
<div className="greeting">
<h3>Hello {this.props.fullName}</h3>
</div>
);
}
}
const element1 = document.getElementById('greeting1')
// Use the ReactDOM.render to show your component on the browser
ReactDOM.render(
<Greeting fullName='Tran' />,
element1
)
props-example.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ReactJS Props</title>
<script src="https://unpkg.com/react@16.4.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.4.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
<style>
.greeting {
border: 1px solid #bdbcae;
background-color: #fbfad9;
margin: 5px 0px;
padding: 5px;
}
</style>
</head>
<body>
<h1>Props example:</h1>
<div id="greeting1"></div>
<script src="props-example.jsx" type="text/babel"></script>
</body>
</html>
Запустите ваш HTTP Server и запустите файл props-example.html. И вы получите результат как в изображении ниже:

В ReactJS когда вы создаете Component, похоже на то, когда вы создаете ваш собственный новый тег (tag). Каждый property у Component будет соответствовать attribute (атрибуту) тега. (Смотрите изображение ниже).

Значение attribute (У тега) будет передано (pass) property (У Component). Но вы можете создать значения по умолчанию для property.
OK следующий пример. В данном примере вы создаете Component с его property, к которым будут прикреплены (assign) значения по умолчанию:
props-example2.jsx
class Welcome extends React.Component {
render() {
return (
<div className="welcome">
<h3>Hi {this.props.name}!</h3>
<i>{this.props.message}</i>
</div>
);
}
}
// Default values of props
Welcome.defaultProps = {
name: "There",
message:"Welcome to Website!"
}
const element1 = document.getElementById('welcome1')
const element2 = document.getElementById('welcome2')
ReactDOM.render(
<Welcome name='Tran' message='Welcome back!' />,
element1
)
ReactDOM.render(
<Welcome />,
element2
)
props-example2.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ReactJS Props</title>
<script src="https://unpkg.com/react@16.4.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.4.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
<style>
.welcome {
border: 1px solid #bdbcae;
background-color: #fbfad9;
margin: 5px 0px;
padding: 5px;
}
</style>
</head>
<body>
<h1>Props example:</h1>
<div id="welcome1"></div>
<div id="welcome2"></div>
<script src="props-example2.jsx" type="text/babel"></script>
</body>
</html>
Запустить файл props-example2.html:

Создать один Component с названием Welcome, и создать значения для property:

Если один определенный attribute не сможет появиться на теге, считается что его значение будет по умолчанию:

Заключение:
- Вы можете создать значения по умолчанию для props.someProp.
- Вы можете настроить значения для props.someProp из attribute someProp тега.
- Изнутри Component (class) у вас нет способов для прикрепления новых значений для props.someProp.
Примечание: На самом деле есть метод, чтобы вы смогли сменить значение props, как например setProps(), replaceProps(), но данные методы не были приняты (Deprecated) с версии ReactJS 0.15. Таким образом можно заключить props является неизменным (immutable).
3. ReactJS state
state (Статус) это принцип в React, довольно похож на props. Перед тем как сравнивать state и props рассмотрим пример:
state-example.jsx
// Create a ES6 class component
class Button extends React.Component {
constructor(props) {
super(props);
this.state = {
text: "Please Click me!",
clickCount: 0
};
}
// Method updateCount()
updateCount() {
this.setState((prevState, props) => {
return {
clickCount: prevState.clickCount + 1,
text: "Clicked"
};
});
}
render() {
return (
<button onClick={() => this.updateCount()}>
{this.state.text} : {this.state.clickCount}
</button>
);
}
}
// Render
ReactDOM.render(<Button />, document.getElementById("button1"));
// Render
ReactDOM.render(<Button />, document.getElementById("button2"));
state-example.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ReactJS State</title>
<script src="https://unpkg.com/react@16.4.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.4.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
</head>
<body>
<h1>State example:</h1>
<div id="button1"></div>
<br>
<div id="button2"></div>
<script src="state-example.jsx" type="text/babel"></script>
</body>
</html>
Запустить файл state-example.html наHTTP и смотрим как он работает.

ПредупреждениеВы не можете настроить новое значение для state по следующим способам, так как React не слышит перемены у state по такому способу, поэтому Component не будет re-render (Переизображен) на интерфейсе.Error!!// Do not do this: this.state.clickCount = this.state.clickCount + 1 // And do not do this: this.setState({ clickCount: this.state.clickCount + 1 });
Заключение:
- props.someProp соответствует attribute (атрибуту) тега, но state.someState не соответствует.
- Вы можете создать значение по умолчанию для state.someState в constructor у class (Component).
- В Component (class) вы не можете изменить значение props.someProp, но можете изменить значение state.someState.
4. ReactJS state (2)
OK, следующий пример. В данном примере мы создадим двустороннюю связь между значениями элемента <input> и state:

Когда статус Component меняется, ReactJS re-render (переизобразит) данный Component на интерфейсе. Если пользователь меняет содержание на элементе <input>, данное значение будет обновлено для объекта state у Component через событие onChange.

state-example2.jsx
class Search extends React.Component {
constructor(props) {
super(props);
this.state = {
searchText: "",
searchCount: 0,
resultCount: 0
};
}
changeSearchText(event) {
var v = event.target.value;
this.setState((prevState, props) => {
return {
searchText: v
};
});
}
doSearch() {
this.setState( (prevState, props) => {
var count = this.state.searchText.length * 3;
return {
searchCount: prevState.searchCount + 1,
resultCount: count
};
});
}
render() {
return (
<div className='search-box'>
<input
type="text"
value={this.state.searchText}
onChange={this.changeSearchText.bind(this)}
/>
<button onClick={this.doSearch.bind(this)}>Search</button>
<div>Search Text: {this.state.searchText}</div>
<div>Search Count: {this.state.searchCount}</div>
<div>Result Count: {this.state.resultCount}</div>
</div>
);
}
}
// Render
ReactDOM.render(<Search />, document.getElementById("search1"));
state-example2.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ReactJS State</title>
<script src="https://unpkg.com/react@16.4.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.4.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
<style>
.search-box {
border:1px solid #cbbfab;
padding: 5px;
}
</style>
</head>
<body>
<h1>State example:</h1>
<div id="search1"></div>
<script src="state-example2.jsx" type="text/babel"></script>
</body>
</html>
Запустить файл state-example2.html на HTTP Server и смотрим как он работает.

Pуководства ReactJS
- Руководство ReactJS props и state
- Руководство ReactJS Events
- Руководство ReactJS Component API
- Методы в жизненном цикле ReactJS Component
- Руководство ReactJS Refs
- Руководство ReactJS Lists и Keys
- Руководство ReactJS Form
- Понимание ReactJS Router с примером на стороне клиента
- Введение в Redux
- Простой пример с React и Redux на стороне клиента
- Руководство React-Transition-Group API
- Быстрый запуск с ReactJS в среде NodeJS
- Понимание ReactJS Router с базовым примером (NodeJS)
- Пример React-Transition-Group Transition (NodeJS)
- Пример React-Transition-Group CSSTransition (NodeJS)
- Введение в ReactJS
- Установка React Plugin для редактора Atom
- Создание простого HTTP Server с NodeJS
- Быстрый запуск с ReactJS - Hello ReactJS
Show More