betacode

Руководство ReactJS props и state

  1. Подсказка
  2. ReactJS props
  3. ReactJS state
  4. ReactJS state (2)

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) propertyComponent). Но вы можете создать значения по умолчанию для 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 и смотрим как он работает.