Mobx – Quản lý state trong React – Part 2

Lời nói đầu Part 1 mình đã hướng dẫn cách viết mobx cơ bản và cách kết hợp mobx với react. Nay mình sẽ hướng dẫn các bạn một số function đặc biệt trong mobx và mobx-react useLocalStore – giải pháp thay thế useState hook Bình thường trong function component chúng ta muốn dùng state

Lời nói đầu

Part 1 mình đã hướng dẫn cách viết mobx cơ bản và cách kết hợp mobx với react. Nay mình sẽ hướng dẫn các bạn một số function đặc biệt trong mobxmobx-react

useLocalStore – giải pháp thay thế useState hook

Bình thường trong function component chúng ta muốn dùng state ta sẽ dùng useState

const[name, setName]=useState('Hello');

Chúng ta hãy tưởng tượng có 10 state lại phải có 10 function đóng vai trò setState đi cùng. Thật là nhiều phải không? Tuy nhiên, nếu chúng ta dùng useLocalStore, một function built-in nằm trong mobx-react thì không cần như thế nữa. Khi dùng function này chúng ta sẽ có một local store cỡ nhỏ. Việc thay đổi nó sẽ dựa vào việc mutate trực tiếp Bạn hãy nhìn ví dụ dưới đây:

import React from"react";import{ useLocalStore, observer }from"mobx-react";exportconst CounterWithLocalStore =observer(()=>{// Khai báo một storeconst store =useLocalStore(()=>({
    count:0,increase:()=>(store.count +=1),// việc thay đổi sẽ được mutate trực tiếpdecrease:()=>(store.count -=1),reset:()=>(store.count =0)}));const{ count, increase, decrease, reset }= store;return(<><p>Count(with local store):{count}</p><button onClick={increase}>Increase +</button><button onClick={decrease}>Decrease -</button><button onClick={reset}>Reset</button></>);});

computed – giá trị sẽ được tính toán lại mỗi khi observable value thay đổi

import{ observable, computed }from"mobx"classOrderLine{
    @observable price =0
    @observable amount =1constructor(price){this.price = price
    }// Giá trị này sẽ được tính toán và trả về mỗi khi 2 giá trị observable ở trên bị thay đổi
    @computed gettotal(){returnthis.price *this.amount
    }}
OrderLine.price =12;

console.log(OrderLine.total)// 12

autorun – thường dùng cho việc log thông tin

Có vài điều cần lưu ý về autorun

  • Cũng giống như computed cũng sẽ chạy khi observable thay đổi, tuy nhiên autorun không trả về giá trị mới
  • autorun trả về một disposer function, hàm này có vai trò huỷ bỏ autorun
  • Tham số thứ nhất mà autorun trả về một biến dùng để debug
import{ observable, computed, autorun }from"mobx"classOrderLine{
    @observable price =0
    @observable amount =1constructor(price){this.price = price;autorun((reaction)=>{
          console.log(this.total)if(this.total >10){
            reaction.dispose();// dừng log lại nếu total > 10}})}// Giá trị này sẽ được tính toán và trả về mỗi khi 2 giá trị observable ở trên bị thay đổi
    @computed gettotal(){returnthis.price *this.amount
    }}

OrderLine.price =9;// log ra 9
OrderLine.price =11;// log ta 11 sau đó bị huỷ bỏ
OrderLine.price =12:// ngưng log vì đã bị huỷ bỏ

when – xảy ra với điều kiện nào

Đôi lúc các bạn sẽ muốn biết khi nào dữ liệu đấy thay đổi và sẽ thay đổi khi nó phù hợp với điều kiện nào

import{ observable, computed, when }from"mobx"classOrderLine{
    @observable price =0
    @observable amount =1constructor(price){this.price = price;// chỉ chạy một lần// Khi this.total lớn hơn 10 thì gán lại this.total = 0when(()=>this.total >10,()=>(this.total =0));}// Giá trị này sẽ được tính toán và trả về mỗi khi 2 giá trị observable ở trên bị thay đổi
    @computed gettotal(){returnthis.price *this.amount
    }}

OrderLine.price =11;
console.log(OrderLine.total)// 0

reaction – một phiên bản nâng cấp so với autorun

reaction nhận vào hai tham số, cả hai đều là function

  • function thứ nhất (data function) là function đóng vai trò là dữ liệu được theo dõi, dữ liệu trả lại sẽ là đầu vào cho function thứ hai
  • function thứ hai (effect function) có hai tham số được trả về, tham số thứ nhất là dữ liệu từ function thứ nhất, tham số thứ hai là reaction (vai trò như trong autorun)
import{ observable, computed, reaction }from"mobx"classTodo{
    @observable todos =[{
          title:"Make coffee",
          done:true,},{
          title:"Find biscuit",
          done:false,},]constructor(price){// reaction 1// Cách sửa dụng reaction sai: nó chỉ theo dõi dộ dài của array todosreaction(()=> todos.length,(length)=> console.log("reaction 1:", todos.map((todo)=> todo.title).join(", ")))// reaction 2// Cách sửa dụng đúng: nó sẽ theo dõi cả độ dài và khi titles thay đổireaction(()=> todos.map((todo)=> todo.title),(titles)=> console.log("reaction 2:", titles.join(", ")))}}

Todo.todos.push({ title:"explain reactions", done:false})// prints:// reaction 1: Make coffee, find biscuit, explain reactions// reaction 2: Make coffee, find biscuit, explain reactions

Todo.todos[0].title ="Make tea"// prints:// reaction 2: Make tea, find biscuit, explain reactions

Kết luận

Qua hai phần về mobx, mình đã giới thiệu cho các bạn cách dùng mobx với react cũng như các function thường sử dụng đi kèm. Mong các bạn các bạn làm việc thật tốt với mobx. Thanks!

Nguồn: viblo.asia

Bài viết liên quan

WebP là gì? Hướng dẫn cách để chuyển hình ảnh jpg, png qua webp

WebP là gì? WebP là một định dạng ảnh hiện đại, được phát triển bởi Google

Điểm khác biệt giữa IPv4 và IPv6 là gì?

IPv4 và IPv6 là hai phiên bản của hệ thống địa chỉ Giao thức Internet (IP). IP l

Check nameservers của tên miền xem website trỏ đúng chưa

Tìm hiểu cách check nameservers của tên miền để xác định tên miền đó đang dùn

Mình đang dùng Google Domains để check tên miền hàng ngày

Từ khi thông báo dịch vụ Google Domains bỏ mác Beta, mình mới để ý và bắt đầ