betacode

Методы в жизненном цикле ReactJS Component

  1. Component Lifecycle
  2. UNSAFE_componentWillMount()
  3. componentDidMount()
  4. componentWillReceiveProps (nextProps)
  5. shouldComponentUpdate (nextProps,nextState)
  6. UNSAFE_componentWillUpdate (nextProps,nextState)
  7. componentDidUpdate (prevProps,prevState)

1. Component Lifecycle

Ряд перемен, которые проходит Component с момента создания до окончания (отменты) называется жизненный цикл (lifecycle) у Component. В процессе существования Component, будут вызваны методы. Ниже является изображение жизненного цикла Component и методы, которые будут вызваны в разных стадиях.
С версии 16.3, некоторые методы в жизненном цикле Component были переименованы, они добавили приставку "UNSAFE_" как предупреждение о том, чтобы вы были осторожны при переопределении (Override) данного метода, так как эти методы часто неправильно понимаются и используются. Они могут создать проблемы с "Async Rendering".

2. UNSAFE_componentWillMount()

Метод UNSAFE_componentWillMount вызван перед тем, как ReactJS вызывает метод render() для изображения (render) Component на интейфейс в первый раз. Этот метод может быть выполнен двумя сторонами Server и Client.
Метод UNSAFE_componentWillMount дает вам возможность кофигурировает, обновлять статус, рассчитать значения, чтобы подготовить для первого render (изображения). В это время state и props были определены, вы можете безопасно запросить this.state, this.props и знать их точные значения.
person.jsx
class Person extends React.Component {
  constructor(props) {
    super(props);
    this.state = { mode: undefined };
  }

  UNSAFE_componentWillMount() {
    let modeValue;
    if (this.props.age > 70) {
      modeValue = "old";
    } else if (this.props.age < 18) {
      modeValue = "young";
    } else {
      modeValue = "middle";
    }
    this.setState({ mode: modeValue });
  }

  render() {
    return (
      <div className={"person person-" + this.state.mode}>
        {this.props.name} (age: {this.props.age})
      </div>
    );
  }
}

Person.defaultProps = { age: "unknown" };

// Render
ReactDOM.render(
  <Person name="Donald Trump" age="72" />,
  document.getElementById("person1")
);
ReactDOM.render(
  <Person name="Ivanka Trump" age="36" />,
  document.getElementById("person2")
);
person.html
<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <title>ReactJS UNSAFE_componentWillMount()</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>
         .person  {
         border:1px solid #cbbfab;
         width: 250px;
         height: 50px;
         padding: 5px;
         margin: 5px;
         }
         .person-old {
         background-color: Gray;
         }
         .person-middle {
         background-color: LightGray;
         }
         .person-young {
         background-color: white;
         }
      </style>
   </head>
   <body>
      <h1>UNSAFE_componentWillMount():</h1>

      <div id="person1"></div>
      <div id="person2"></div>

      <script src="person.jsx" type="text/babel"></script>
   </body>
</html>
Запустить пример:

3. componentDidMount()

Метод componentDidMount() вызван сразу же после того, как Component был изображен (render) на интерфейсе в первый раз, он был выполнен Client (клиентом).
Метод componentDidMount() вызывается, когда Component был render (изображен) на интейрфейсе 1 раз, поэтому в данном методе вы можете получить доступ к Native UI (DOM, UIView,..), чтобы сделать определенное действие. Вы так же можете вызвать другую библиотеку Javascript в данном методе, например вызвать библиотеку диаграмм (Chart), чтобы отобразить диаграмму данных у Component.
Метод componentDidMount() так же может быть местом, где вы используете AJAX для получения данных из Server, потом вызываете setState(), чтобы сменить статус Component, если удачно, то Component будет render (изображен) еще 1 раз.
Example:
OK, в данном примере я симулирую скачивание (load) данных из Server в методе componentDidMount().
employee.jsx
class Employe extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      loaded: false,
      empId: "[empId]",
      fullName: "[fullName]"
    };
  }

  // Load data from Server..
  loadEmployeeData() {
    setTimeout(() => {
      console.log("Data is loaded");
      this.setState({
        loaded: true,
        empId: this.props.empId,
        fullName: "Emp " + Math.random()
      });
    }, 1000);
  }

  componentDidMount() {
    this.loadEmployeeData();
  }

  render() {
    if (this.state.loaded == true) {
      return (
        <div className="employee">
          <p>Emp Id: {this.state.empId}</p>
          <p>Full Name: {this.state.fullName}</p>
        </div>
      );
    } else {
      return (
        <div className="employee">
          <p>
            Wait while data loading. EmpID: {this.props.empId}
          </p>
        </div>
      );
    }
  }
}

// Render
ReactDOM.render(<Employe empId="1" />, document.getElementById("employee1"));
employee.html
<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <title>ReactJS componentDidMount()</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>
         .employee  {
         border:1px solid #cbbfab;
         padding: 5px;
         margin: 5px;
         }
      </style>
   </head>
   <body>
      <h1>componentDidMount():</h1>
      
      <div id="employee1"></div>

      <script src="employee.jsx" type="text/babel"></script>
   </body>
</html>
Запустить файл employee.html на HTTP Server:

4. componentWillReceiveProps (nextProps)

5. shouldComponentUpdate (nextProps,nextState)

Метод shouldComponentUpdate() возвращает true/false, вызывается после того, как Component установил новый статус через метод setState(). В shouldComponentUpdate() вы можете решить стоит или не стоит re-render (переизображать) Component на интерфейсе.
  • Если метод возвращает true то Component будет re-render (переизображен) на интерфейсе.
  • Если метод возвращает false, ничего не будет выполнено далее.
odd-number.jsx
class NumberView extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      currentNumber: 1
    };
  }

  nextValue() {
    this.setState((prevState, props) => {
      return {
        currentNumber: prevState.currentNumber + 1
      };
    });
  }

  shouldComponentUpdate(nextProps, nextState) {
    // Odd Number
    return nextState.currentNumber % 2 == 1;
  }

  render() {
    return (
      <div className="number-viewer">
        <button onClick={() => this.nextValue()}>Next Value</button>
        <p>Current Value: {this.state.currentNumber}</p>
      </div>
    );
  }
}

// Render
ReactDOM.render(<NumberView />, document.getElementById("numberview1"));
odd-number.html
<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <title>ReactJS shouldComponentUpdate()</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>
         .number-view  {
         border:1px solid #cbbfab;
         padding: 5px;
         margin: 5px;
         }
      </style>
   </head>
   <body>
      <h1>shouldComponentUpdate():</h1>

      <p>Show only odd numbers</p>
      <div id="numberview1"></div>

      <script src="odd-number.jsx" type="text/babel"></script>
   </body>
</html>

6. UNSAFE_componentWillUpdate (nextProps,nextState)

Метод UNSAFE_componentWillUpdate(nextProps,nextState) это место, позволяющее конфигурировать или рассчитать значения перед тем, как Componentre-render (переизображен). Этот метод довольно схож с методом UNSAFE_componentWillMount(). Отличием является то, что в данном методе вы можете получить доступ к следующим статусам Component через параметры nextState.
Примечание: В методе UNSAFE_componentWillUpdate(nextProps,nextState) вам нельзя вызывать setState(), так как он может создать бесконечный цикл.
revenue.jsx
class RevenueView extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      year: 2018,
      revenue: 1000,
      growthRate: "Unknown"
    };
  }

  nextYear() {
    this.setState((prevState, props) => {
      var randomRevenue = prevState.revenue * (1 + Math.random());
      return {
        year: prevState.year + 1,
        revenue: randomRevenue
      };
    });
  }

  UNSAFE_componentWillUpdate(nextProps, nextState) {
    var rate = (nextState.revenue - this.state.revenue) / this.state.revenue;
    nextState.growthRate = 100 * rate + " %";
  }

  render() {
    return (
      <div className="revenue-view">
        <p>Year: {this.state.year}</p>
        <p>Revenue: {this.state.revenue}</p>
        <p>Growth Rate: {this.state.growthRate}</p>
        <button onClick={() => this.nextYear()}>Next Year</button>
      </div>
    );
  }
}

// Render
ReactDOM.render(<RevenueView />, document.getElementById("revenueview1"));
revenue.html
<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <title>ReactJS UNSAFE_componentWillUpdate(props,nextState)</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>
         .revenue-view  {
         border:1px solid #cbbfab;
         padding: 5px;
         margin: 5px;
         }
      </style>
   </head>
   <body>
      <h3>UNSAFE_componentWillUpdate(nextProps,nextState):</h3>

      <div id="revenueview1"></div>

      <script src="revenue.jsx" type="text/babel"></script>
   </body>
</html>

7. componentDidUpdate (prevProps,prevState)

  • TODO !!