Component phần 5: React

React là 1 thư viện được phát triển bởi Facebook, được đông đảo cộng đồng chấp nhận và trở nên cực kì phổ biến. Có rất nhiều job trên thị trường yêu cầu phải biết React. React là 1 trong các thư viện đầu tiên và phổ biến nhất tiên phong trong phong cách "phân tách dữ liệu và giao diện" (declarative progamming).

Một số điểm nhấn quan trọng của React:

  • sử dụng state, khi state thay đổi thì render sẽ chạy lại. những phong cách viết code ở các bài trước là học hỏi theo react, tuy nhiên xử lý sẽ không được gọn gàng bằng react được.

  • có thể viết code html bên trong JS và đặt listener ngay trong đoạn code html. Bạn không cần dùng template string để tạo string html nữa, mà ở bên JS bạn return thẳng html luôn. Cái này gọi là JSX, thật ra điều này không hợp lý với syntax của JS, tức là trên lý thuyết code đó sẽ không thể chạy được. React đã giới thiệu "build step", tức là code của bạn sẽ được convert sang định dạng mà JS có thể chạy được, và trên trình duyệt sẽ chạy cái code đã được build đó thay vì những cái bạn viết trực tiếp.

  • đi kèm với React là 1 loạt các khái niệm nâng cao, và các kiến thức update liên tục. Nội tại React: useState, useEffect, context, props... Ngôn ngữ Typescript, syntax import export... Các công cụng dùng cho build step: Webpack, create react app, Vite,... Các thư viện liên quan đến style: css in js (jss), css module, styled-component,... Các thư viện liên quan đến state management: redux, mobx, jotai, zustand,...

    Đó là lý do học React rất dễ ngợp, có quá nhiều thư viện và cách sử dụng. Trong series này mình sẽ hạn chế giới thiệu càng ít thư viện càng tốt, sẽ không giống nhiều blog viết về React khác.

Thử React với JSBin

Đầu tiên, đặt 1 div bất kì trong <body />. VD ở đây là <div id="root"></div>.

Sau đó chèn đoạn script sau vô:

<script src="https://cdn.jsdelivr.net/npm/react@18.2.0/umd/react.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/react-dom@18.2.0/umd/react-dom.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@babel/standalone@7.23.5/babel.min.js"></script>

Và sau đó tạo 1 thẻ script để viết code trong đó. thẻ script này sẽ phải có type là "text/babel"

<script type="text/babel" data-presets="env,react">
    const Home = () => {     
      const [count, setCount] = React.useState(0);
      return (
        <div>
          Hell world
          <p>{count}</p>
          <button onClick={() => setCount(count + 1)}>+</button>
        </div>
      );
    };
    ReactDOM.render(<Home />, document.querySelector('#root'))
</script>

Mặc định type của script sẽ là "text/javascript", nếu bạn đặt 1 type khác thì nó sẽ không chạy code bên trong. Đó là lý do chúng ta cần babel.min.js để chạy type "text/babel". Babel sẽ build code trực tiếp và chạy nó cho chúng ta. Lưu ý rằng babel rất nặng nên với các app lớn, build code trực tiếp sẽ load rất lâu, do đó cách này chủ yếu để demo thôi, trong các dự án thực tế, không build code trực tiếp khi chạy, mà sẽ build từ trước và chỉ chạy code đã đc build.

Như ví dụ trên là cách tạo 1 bộ đếm với React function. quản lý state bằng useState, ở đây k có function render, mà mặc định là code html ở trong function return sẽ đc render mỗi khi setState.

Dưới đây là 1 VD khác chạy bằng React class

class Home extends React.Component {

      state = { count: 0 };
      render() {
        return (
          <div>
            Hell world
            <p>{this.state.count}</p>
            <button onClick={() => this.setState({
              count: this.state.count + 1
             })}>+</button>
          </div>
        );
      }

    }
    ReactDOM.render(<Home />, document.querySelector('#root'))

Về cơ bản thì concept cũng giống, ở class thì đã thấy method render, nhưng vì là class nên sẽ có this. React class hiện giờ ít phổ biến hơn vì mọi người chuộng viết React function hơn, do việc dùng useState tiện hơn, dễ tái sử dụng cho nhiều Component. Về cơ bản, mọi thứ làm được bằng React function, đều có thể làm được bằng React class, chỉ là 2 cách viết khác nhau. Nó cũng giống như việc dùng function và class nói chung trong JS, concept và syntax khác nhau, nhưng hầu như mọi trường hợp đều có thể dùng thay thế lẫn nhau.

Các trường phái React

Như đã giới thiệu ở bên trên, React cực kì rộng lớn, không phải vì thư viện React có rất nhiều tính năng. Bộ core của nó chỉ có 1 số các cách dùng. Cái rộng lớn ở đây là cộng đồng sử dụng, họ build thêm các thư viện phụ trợ cho React. Và do đó sẽ chia thành rất nhiều trường phái. Thông thường vòng đời của 1 project có thể tính bằng nhiều năm, do đó, khi bạn làm xong dự án đến giai đoạn sản phẩm ổn định rồi thì đã mọc ra rất nhiều trường phái khác mà bạn chưa biết. Do đó, cách duy nhất để thích ứng là không ngừng research và học hỏi, nhất là khi bạn định nhảy việc và tech lead bên đó sử dụng React theo 1 trường phái khác.

Trường phái của series này sẽ là "code chay nhiều nhất có thể". Sử dụng càng ít thư viện càng tốt, ưu tiên việc tự code các function riêng của mình. Đó là cách nhanh nhất để học hỏi việc code frontend. Ngoài ra series này sẽ sử dụng Wordpress + Elementor làm nền móng. Do đó, song song với việc sử dụng React, b có thể sử dụng UI Builder và Web Component. Cái này có thể gọi là việc làm website theo hướng micro-frontend.

Chỉnh sửa Elementor 1 chút và thêm 1 số tính năng trước khi code

Mặc định Elementor không cung cấp đủ số lượng block cần thiết để bạn build website, và Elementor thậm chí không cung cấp/ không hỗ trợ việc tạo thêm layout block (block mà có thể nhận block khác làm children, giống block Container). Do đây là 1 plugins có phiên bản Pro và có Marketplace nên mục tiêu của họ sẽ là kiếm lợi nhuận từ những người không biết code, nên sẽ không hy vọng gì họ bổ sung các block hữu dụng cho việc làm component (chủ yếu dùng cho những người biết code). Mình đã chỉnh sửa Elementor 1 chút, kèm thêm phát triển 1 plugin cho Elementor để có thể:

  • code trực tiếp React trên Elementor, có build step tích hợp sẵn.

  • có thể code bằng editor giống VS Code.

  • có thể dùng thẻ <form /> và thẻ <template /> (hỗ trợ cho bài viết Component phần 3).

Bạn nào cần bộ code này thì liên hệ với mình qua email , hoặc mình sẽ tìm cách publish nó ở các bài sau trong series.

Một số screenshot:

Và đây là video: