openplanning

Xử lý sự kiện (Event) trong ReactJS

Xem thêm các chuyên mục:

Nhóm phát triển của chúng tôi vừa ra mắt website langlearning.net học tiếng Anh, Nga, Đức, Pháp, Việt, Trung, Hàn, Nhật, ... miễn phí cho tất cả mọi người.
Là một website được viết trên công nghệ web Flutter vì vậy hỗ trợ rất tốt cho người học, kể cả những người học khó tính nhất.
Hiện tại website đang tiếp tục được cập nhập nội dung cho phong phú và đầy đủ hơn. Mong các bạn nghé thăm và ủng hộ website mới của chúng tôi.
Hãy theo dõi chúng tôi trên Fanpage để nhận được thông báo mỗi khi có bài viết mới. Facebook
Trong bài học này tôi sẽ hướng dẫn bạn "Làm sao để sử dụng Event (sự kiện) trong ReactJS". Cũng không có nhiều khác biệt khi bạn sử dụng các event trong ReactJS so với sử dụng các event trong Javascript.
  • Trong Javascript bạn sẽ xử lý sự kiện trong một hàm, còn trong React bạn sẽ xử lý sự kiện trong một phương thức của Component.

1- ReactJS Events

React là một thư viện dựa trên Javascript, về cơ bản không có nhiều khác biệt trong cách xử lý sự kiện giữa ReactJSJavascript. Với Javascript, khi sự kiện xẩy ra một hàm sẽ được gọi để thực thi. Nhưng với React, khi sự kiện xẩy ra, sẽ có một phương thức của Component được gọi.
OK, trước hết hãy xem một ví dụ đơn giản:
onClick-example.html

class CurrentTime extends React.Component {
  constructor(props) {
    super(props);

    var now = new Date();
    this.state = {
      currentTime: now.toString()
    };
  }

  // A method of CurrentTime component
  refreshCurrentTime() {
    var now = new Date();
    this.setState({ currentTime: now.toString() });
  }
  render() {
    return (
      <div>
        <h4>Current Time:</h4>
        <p>{this.state.currentTime}</p>
        <button onClick={() => this.refreshCurrentTime()}>
          Refresh Current Time
        </button>
      </div>
    );
  }
}

// Render
ReactDOM.render(<CurrentTime />, document.getElementById("currenttime1"));
onClick-example.html

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <title>ReactJS Event</title>
      <script src="https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
      <script src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>
      <script src="https://unpkg.com/[email protected]/babel.min.js"></script>
      <style>
         #currenttime1 {
         border:1px solid blue;
         padding: 5px;
         margin-top: 20px;
         }
      </style>
   </head>
   <body>
      <h3>ReactJS Event: onClick</h3>

      <div id="currenttime1"></div>

      <script src="onClick-example.jsx" type="text/babel"></script>

   </body>
</html>
Arrow Function
Với cú pháp Javascript ES6 bạn có thể tạo một arrow function (Hàm mũi tên), rất ngắn gọn và dễ hiểu:
** arrow function **

// Normal function with parameters
var myfunc = function(param1, param2)  {
   // Statements
};

// Arrow function with parameters.
var arrfunc = (param1, param2) => {
   // Statements
};


// Normal function without paramters.
var myfunc2 = function( )  {
   // Statements
};

// Arrow function without parameters.
var arrfunc2 = ( ) => {
   // Statements
};

// If function have only one statement.
var arrfunc2 = ( ) => singleStatement;
onClick, onChange,..
onClick phải gọi đến một hàm Javascript, nó không thể gọi trực tiếp đến một phương thức của Component. Vì vậy onClick nên gọi đến một hàm nặc danh (anonymous), và bên trong hàm nặc danh này bạn có thể gọi đến phương thức của Component:
Arrow function với tham số event:

// A method of Component with event parameter.
refreshCurrentTime(event) {
  var now = new Date();
  this.setState({ currentTime: now.toString() });
}

render() {
  return (
    <div>
      <h4>Current Time:</h4>
      <p>{this.state.currentTime}</p>
      <button onClick={(event) => this.refreshCurrentTime(event)}>
          Refresh Current Time
      </button>
    </div>
  );
}
Với Javascript ES6 bạn cũng có thể gọi đến phương thức của Component theo cách sau:
.jsx

// A method of this Component.
refreshCurrentTime(event) {
  var now = new Date();
  this.setState({ currentTime: now.toString() });
}

render() {
  return (
    <div>
      <h4>Current Time:</h4>
      <p>{this.state.currentTime}</p>
      <button onClick={this.refreshCurrentTime.bind(this,event)}>
         Refresh Current Time
      </button>
    </div>
  );
}
Hoặc:
onClick-example3.jsx

class CurrentTime extends React.Component {
  constructor(props) {
    super(props);

    var now = new Date();
    this.state = {
      currentTime: now.toString()
    };

    // (***)
    this.refreshCurrentTime = this.refreshCurrentTime.bind(this);
  }

  // A method of this Component
  refreshCurrentTime( ) {
    var now = new Date();
    this.setState({ currentTime: now.toString() });
  }
  render() {
    return (
      <div>
        <h4>Current Time:</h4>
        <p>{this.state.currentTime}</p>
        <button onClick={this.refreshCurrentTime}>
          Refresh Current Time
        </button>
      </div>
    );
  }
}

// Render
ReactDOM.render(<CurrentTime />, document.getElementById("currenttime1"));

2- Event của Component con

Một sự kiện xẩy ra tại Component con, nhưng bạn muốn gọi đến một phương thức tại Componen cha, dưới đây là một ví dụ như thế.
childEvent-example.jsx

// <Child> with 1 attribute: myClickHandler
// <Child myClickHandler=.. />
class Child extends React.Component {
  render() {
    return (
      <div className="child">
        <h4>Child</h4>
        <button onClick={this.props.myClickHandler}>Click me!</button>
      </div>
    );
  }
}

class Parent extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      count: 0
    };
  }

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

  render() {
    return (
      <div className="parent">
        <h3>(Parent) Clicked: {this.state.count} </h3>
        <Child myClickHandler={() => this.myMethodOfParent()} />
      </div>
    );
  }
}

// Render
ReactDOM.render(<Parent />, document.getElementById("placeholder1"));
childEvent-example.html

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <title>ReactJS Event</title>
      <script src="https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
      <script src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>
      <script src="https://unpkg.com/[email protected]/babel.min.js"></script>
      <style>
         .parent {
         border:1px solid #d9ebe8;
         padding: 5px;
         margin-top: 20px;
         }
         .child {
         width:150px;
         border:1px solid #8cb0aa;
         margin: 5px;
         padding: 5px;
         }
      </style>
   </head>
   <body>
      <h3>The child's event calls to parent's method</h3>

      <div id="placeholder1"></div>

      <script src="childEvent-example.jsx" type="text/babel"></script>
      
   </body>
</html>

3- Một ví dụ phức tạp

OK, và bây giờ là một ví dụ phức tạp hơn, nó yêu cầu bạn thông thạo nhiều kiến thức trong ReactJS, chẳng hạn Lists, Props, State, Event..
Các kiến thức trong ReactJS mà bạn cần biết:
complex-example.jsx

// <OrderDetail> with 4 attributes:
// productName, price, quantity, addHandler
class OrderDetail extends React.Component {
  render() {
    return (
      <div className="order-detail">
        <h4>{this.props.productName}</h4>
        <p>Price: {this.props.price} USD</p>
        <p>Quantity: {this.props.quantity}</p>
        <p>
          <button onClick={this.props.addHandler}>+</button>
        </p>
      </div>
    );
  }
}

class Order extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      amount: 0,
      details: [
        { id: 1, productName: "IPhone X", price: 900, quantity: 0 },
        { id: 2, productName: "Samsung S9", price: 800, quantity: 0 },
        { id: 3, productName: "Nokia 8", price: 650, quantity: 0 }
      ]
    };
  }

  updateOrder(index) {
    this.setState((prevState, props) => {
      console.log(this.state.details);

      var newQty = prevState.details[index].quantity + 1;
      this.state.details[index].quantity = newQty;
      this.state.amount = prevState.amount + 1 * prevState.details[index].price;
      return {
        amount: this.state.amount,
        details: this.state.details
      };
    });
  }

  render() {
    // Array of <OrderDetail ../>
    var detailTags = this.state.details.map((e, index) => (
      <OrderDetail
        key={e.id}
        addHandler={() => this.updateOrder(index)}
        productName={e.productName}
        price={e.price}
        quantity={e.quantity}
      />
    ));
    return (
      <div className="order">
        {detailTags}
        <div className="clear" />
        <p className="total">Total: <b>{this.state.amount} USD</b></p>
      </div>
    );
  }
}

// Render
ReactDOM.render(<Order />, document.getElementById("order1"));
complex-example.html

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <title>ReactJS Event</title>
      <script src="https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
      <script src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>
      <script src="https://unpkg.com/[email protected]/babel.min.js"></script>
      <style>
         .order {
           border:1px solid #d9ebe8;
           padding: 5px;
           margin-top: 20px;
         }
         .order-detail {
            float : left;
            width:150px;
            border:1px solid #8cb0aa;
            margin: 5px;
            padding: 5px;
         }
         .clear {
           clear: both;
         }
         .total {
            margin: 5px;
         }
      </style>
   </head>
   <body>
      <h3>Complex Example (Event, List, Props, State)</h3>

      <div id="order1"></div>

      <script src="complex-example.jsx" type="text/babel"></script>

   </body>
</html>

Xem thêm các chuyên mục: