+3

Tìm hiểu cơ bản về Reactjs(phần 2)

Ở phần trước tớ đã giới thiệu và một số yêu cầu trước khi học Reactjs, tiếp theo ở phần này tớ sẽ giới thiệu những phần cốt lỗi của Reactjs giúp chúng ta có cái nhìn tổng quan hơn nhé.

JSX là gì ?

JSX là một cú pháp mở rộng cho javascript, React khuyến khích sử dụng JSX với React để mô tả giao diện (UI). JSX có thể trông giống Ngôn ngữ Khuôn mẫu (Template language), nhưng JSX đi kèm với toàn bộ tính năng của JavaScript.

Cùng tìm hiểu ví dụ này nhé ✌️

const heading = <h1 className="site-heading">Hello, React</h1>

Ở ví dụ này mới thấy lần đầu tớ cũng nghĩ là HTML nhưng không đây là JSX (JavaScript XML). Với JSX chúng ta có thể viết giống như HTML và có thể tạo và sử dụng các thẻ XML của riêng mình.

Dưới đây là một số điểm khác biệt mà chúng ta cần chú ý

  • ClassName được sử dụng thay vì class để thêm các lớp css vì class là một từ khóa dành riêng trong javascript.
  • Property và methods phải là camelCase ví dụ onclick sẽ thành onClick.
  • Các thẻ tự đóng phải được kết thức bởi dấu gạch chéo ví dụ : <img />

Component

Component là một block code độc lập, có thể tái sử dụng, nó mô tả một phần giao diện của ứng dụng và mỗi component sẽ thực hiện nhiệm vụ riêng biệt mà không cần quan tâm nó ảnh hưởng tới các thành phần khác như nào.

Ở đây từ lúc khởi tạo ứng dụng, React đã tạo ra một component có tên là App.js, thư mục này có chức năng load mọi thứ và những component mà bạn khai báo. Những component có thể được gọi là class componentssimple components(Functional component).

Functional component (Simple Component)

Functional component là một hàm javascript (hoặc ES6) trả về một phần tử/element React. chúng ta có thể khai báo component:

function Table() {
  return (
    <tbody>
      <tr>
        <td>Charlie</td>
        <td>Janitor</td>
      </tr>
      <tr>
        <td>Mac</td>
        <td>Bouncer</td>
      </tr>
      <tr>
        <td>Dee</td>
        <td>Aspiring actress</td>
      </tr>
      <tr>
        <td>Dennis</td>
        <td>Bartender</td>
      </tr>
    </tbody>
};

Hoặc cũng có thể sử dụng ES6 Arrow function để tạo component

const Table = () => {
  return (
    <tbody>
      <tr>
        <td>Charlie</td>
        <td>Janitor</td>
      </tr>
      <tr>
        <td>Mac</td>
        <td>Bouncer</td>
      </tr>
      <tr>
        <td>Dee</td>
        <td>Aspiring actress</td>
      </tr>
      <tr>
        <td>Dennis</td>
        <td>Bartender</td>
      </tr>
    </tbody>
}

Cả hai function đều là component hợp lệ, và chúng cũng có tên khác là stateless Component bởi vì chúng không thể làm phức tạp như quản lý state hoặc vòng đời trong function component, Nhưng từ version 16.8 và các tính năng khác.

React Function Compoment là:

  • Một function javascript/ ES6 function.
  • Phải trả về một React element.
  • Nhận props làm tham số nếu cần.

Class Components

Class Component là những class ES6, chúng phúc tạp hơn component ở chỗ nó có phương thức khởi tạo, vòng đời, hàm render(), quản lý state(data). cùng tìm hiểu ví dụ dưới đây :

import React, {Component} from 'react'

class Table extends Component {
  render() {
    return (
      <table>
        <thead>
          <tr>
            <th>Name</th>
            <th>Job</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>Charlie</td>
            <td>Janitor</td>
          </tr>
          <tr>
            <td>Mac</td>
            <td>Bouncer</td>
          </tr>
          <tr>
            <td>Dee</td>
            <td>Aspiring actress</td>
          </tr>
          <tr>
            <td>Dennis</td>
            <td>Bartender</td>
          </tr>
        </tbody>
      </table>
    )
  }
}

export default Table

Bạn có thể hiểu là class Table kế thừa Component, vì vậy React hiểu class này là một component và nó return ra một React Element.

Một React class component là:

  • Là một class ES6, nó sẽ là một component khi nó kế thừa React component
  • Có thể nhận Props(trong hàm khởi tạo nếu cần).
  • Được khởi tạo với vòng đời hoàn chỉnh
  • Phải có method render() trả về 1 React element(JSX) hoặc null

Props

Ở phần Component mình nhắc đến props khá là nhiều chắc mọi người cũng thắc mắc nó là gì. Thì ở đây Props được sinh ra để để giải quyết những dữ liệu cứng có nghĩa là không thay đổi. Nó là một những những ưu điểm về React để xử lý dữ liệu.

Props là một object được truyền vào mỗi component, mỗi component sẽ nhận props và trả về react element, chúng cho phép các component giao tiếp với nhau bằng cách truyền tham số qua lại giữa các component. Cùng xem ví dụ dưới đây nhé :

import React, {Component} from 'react'

class Table extends Component {
    render() {
        const data = [
            {
                name: 'Charlie',
                job: 'Janitor',
            },
            {
                name: 'Mac',
                job: 'Bouncer',
            },
            {
                name: 'Dee',
                job: 'Aspring actress',
            },
            {
                name: 'Dennis',
                job: 'Bartender',
            },
        ];
        return (
          <TableBody data={data} />
      );
  }
}

const TableBody = (props) => {
    const rows = props.data.map((row, index) => {
        return (
            <tr key={index}>
                <td>{row.name}</td>
                <td>{row.job}</td>
            </tr>
        );
    })

    return (<tbody>{rows}</tbody>)

};

export default Table

Ở đây dữ liệu đã được truyền từ table component xuống TableBody component thông qua cú pháp :data={data} ở return.

Props là một cách hiểu quả để chuyển dữ liệu hiện có đến một component React, tuy nhiên component không thể thay đổi props - chúng chỉ ở chế độ đọc, chúng ta sẽ tìm cách sử dụng State để kiểm soát thêm việc xử lý dữ liệu trong React.

State

Ở ví dụ trên, chúng ta đã lưu trữ dữ liệu bằng một array và pass chúng thông qua Props nhưng khi chúng ta muốn xóa một phần tử trong array, đối với Props chúng ta có luồng dữ liệu một chiều, nhưng với State chúng ta có thể cập nhật dữ liệu riêng tư từ một component nào đó.

Chúng ta có thể coi State là bất kì dữ liệu nào cần được lưu trữ và sửa đổi mà không nhất thiết phải được thêm vào cơ sử dữ liệu.

Ví dụ: Thêm và xóa các mặt hàng khỏi giỏ hàng trước khi xác nhận mua hàng.

Cùng tìm hiểu ví dụ nhé :

import React, {Component} from 'react'

class Table extends Component {
    state = {
        data:  [
            {
                name: 'Charlie',
                job: 'Janitor',
            },
        ]
    }
}

Ở đây tớ có :

  • Tạo một đối tượng state
  • Bên trong state chứa những thuộc tính mà bạn muốn lưu.

Tớ cũng đã tạo dữ liệu bên trong state, bây giờ chúng ta thử xóa phần tử bên trong mảng, cùng tạo removeData method bên trong class table nhé.

this.state.data: Để truy xuất state

this.setState(): Để cập nhật state

Dưới đây là toàn bộ code xóa phần tử sử dụng stateprops

import React, {Component} from 'react'

class Table extends Component {
   state = {
       data :  [
           {
               name: 'Charlie',
               job: 'Janitor',
           },
           {
               name: 'Mac',
               job: 'Bouncer',
           },
           {
               name: 'Dee',
               job: 'Aspring actress',
           },
           {
               name: 'Dennis',
               job: 'Bartender',
           },
       ]
   }

   removeData = (index) => {
       const { data } = this.state;
       this.setState({
           data: data.filter((data, i) => {
               return i !== index;
           }),
       })
   }

   render() {
       return (
           <div>
               <table>
                   <TableHeader />
                   <TableBody data={this.state.data} removeData={this.removeData} />
               </table>
           </div>
     );
 }
}

const TableBody = (props) => {
   console.log(props);
   const rows = props.data.map((row, index) => {
       return (
           <tr key={index}>
               <td>{row.name}</td>
               <td>{row.job}</td>
               <td>
                   <button onClick={() => props.removeData(index)}>Delete</button>
               </td>
           </tr>
       );
   })

   return (<tbody>{rows}</tbody>)

};

const TableHeader = () => {
   return (
       <thead>
           <tr>
               <th>Name</th>
               <th>Job</th>
           </tr>
       </thead>
   )
}

export default Table;

Life cycle

Nhìn vào hình ảnh chúng ta có thể chia Life cycle Thành 3 giai đoạn:

  1. Mounting : cho phép người dùng can thiệp vào UI khi khởi tạo một component.

  2. Update: Cập nhật một thuộc tính của component sẽ ở phần từ này.

  3. Unmout: quá trình xảy ra khi các component được xóa khỏi component, nói các khác giai đoạn này được gọi khi không có component nào hoặc người dùng chuyển trang tới trang khác.

Chi tiết từng giai đoạn

  • ComponentWillMount: Đây là một methods sẽ được thực thi ra trước khi component được render, trên cả client hoặc server
  • componentDidMount: method này được thực thi khi một component được render trên client side, đây là nơi các ajax request, DOM hoặc cập nhật state được thực thi.
  • componentReceiveProps: sẽ được thực thi ngay khi Props được update và trước khi component được render lại
  • shouldComponentUpdate sẽ trả về kết quả True hoặc False. phương thức này sẽ xác định component có được update hay không, mặc định sẽ là true, nếu bạn không muốn component render lại sau khi update state hay props thì return thành false.
  • componentWillUpdate: được gọi khi update state của component trước khi chúng render lại.
  • componentDidUpdate được gọi sau khi componentWillUpdate được gọi xong.
  • componentWillUnmout: được gọi khi chúng ta unmount một component.

Cùng tìm hiểu ví dụ nhé:

import React from 'react';

class App extends React.Component {
      state = {
         data: 0
      }
   setNewNumber = () => {
      this.setState({data: this.state.data + 1})
   }
   render() {
      return (
         <div>
            <button onClick = {this.setNewNumber}>INCREMENT</button>
            <Content myNumber = {this.state.data}></Content>
         </div>
      );
   }
}
class Content extends React.Component {
   UNSAFE_componentWillMount() {
      console.log('Component WILL MOUNT!')
   }
   componentDidMount() {
      console.log('Component DID MOUNT!')
   }
   UNSAFE_componentWillReceiveProps(newProps) {    
      console.log('Component WILL RECIEVE PROPS!')
   }
   shouldComponentUpdate(newProps, newState) {
      return true;
   }
   UNSAFE_componentWillUpdate(nextProps, nextState) {
      console.log('Component WILL UPDATE!');
   }
   componentDidUpdate(prevProps, prevState) {
      console.log('Component DID UPDATE!')
   }
   componentWillUnmount() {
      console.log('Component WILL UNMOUNT!')
   }
   render() {
      return (
         <div>
            <h3>{this.props.myNumber}</h3>
         </div>
      );
   }
}
export default App;

Cùng xem từng giai đoạn nhé :

  • Mounting: Ở giai đoạn này 2 method componentWillMountcomponentDidMount được thực thi:
  • Update: Ở giai đoạn này chúng ta click vào button INCREMENT quá trình update state xảy ra và lifce cyle sẽ được thực hiện thông qua method componentWillReceiveProps, componentWillUpdatecomponentDidUpdate
  • Unmout: Ở phần này chúng ta cùng can thiệp vào file src/index.js để setTimeout unmout component để nó có thể xuất hiện sự kiện component được xóa.
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

ReactDOM.render(<App />, document.getElementById('root'));

reportWebVitals();

setTimeout(() => {
  ReactDOM.unmountComponentAtNode(document.getElementById('root'));
}, 5000);

Ở đây tớ để 5s để chúng tự unMount component công việc chúng ta là chờ để nó xóa component thôi và kết quả là:

Kết Luận

Ở bài viết này tớ đã giới thiệu những phần cơ bản nhất về component ReactJs, trong bài viết tiếp tớ sẽ thao tác CRUD và có thể call API cho vui và bài viết của tớ đến đây là hết.

Cảm ơn các cậu bỏ chút thời gian tới bài viết của tớ, chúc mọi người có một ngày làm việc và học tập vui vẻ :3.


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.