Một ít về React

Trong công việc, những xử lý JS ở brower đôi khi khá lằng nhằng dẫn đến việc quản lý gặp nhiều khó khăn, React gíup cho các xử lý JS được dễ quản lý hơn.

Link: https://facebook.github.io/react/

Ta thường tạo 1 component trong React như sau:

import ...
export default class OrderDetailList extends Component {
   constructor(props) {
     super(props)
    
     this.store = {...}
     this.state = {...}
   }
   
   render() {
       return (
           ...
       )
   }
}

Store để lưu gía trị, khi thay đổi những gía trị trong Store thì trên giao diện không có thay đổi. State cũng dùng để lưu gía trị, nhưng khi thay đổi thì những chỗ trên giao diện có sử dụng gía trị này sẽ thay đổi theo. Ta dùng method setState (https://facebook.github.io/react/docs/react-component.html#setstate)

Ví dụ ta có 1 component như sau:

import ...
export default class OrderDetailList extends Component {
   constructor(props) {
     super(props)
     
     this.state = {
         name: this.props.name
     }
   }
   
   onClickChangeName() {
     this.setState({name: "New name"})
   }
   
   render() {
       return (
         <div onClick={() => this.onClickChangeName()}>
           {this.state.name}
         </div>
       )
   }
}

Trong Component này, hàm onClickChangeName sử dụng hàm setState để change name trong State đồng thời thay đổi name trên view.

Việc thay đổi State trong 1 component không có gì phức tạp, vậy muốn thay đổi State của 1 component khác thì phải làm như thế nào? Ví dụ khi render 1 list order, mỗi khi thay đổi name 1 order thì sẽ báo số lượng order đã thay đổi name.

Ta sẽ có 1 component list:

import ...
import OrderDetail from ...
import OrderStore from ...

export default ListOrder extends Component {
  constructor(props) {
    super(props)
     
    OrderStore.orders = this.props.orders
    
    this.state = {
      orders: OrderStore.all.orders,
      changed_count: 0
    }
  }
  
  renderListOrder() {
      const list = this.state.orders.map((order) => {
        return(<OrderDetail key={order.id} order={order}>)
      })
  }
  
  componentDidMount() {
    OrderStore.addListener(() => this.setState(OrderStore.all))
  }
  
  render() {
    return (
      <div>
          {this.state.unchange_count}
          {this.renderListOrder}
      </div>
    )
  }
}

1 component detail:

import ...
import OrderAction from ...

export default OrderDetail extends Component {
  constructor(props) {
    super(props)
     
    this.state = {
      order: this.props.order
    }
  }
  
  onClickChangeName() {
    OrderAction.changeName(this.props.order)
  }

  render() {
    return (
      <div onClick={() => this.onClickChangeName()}>
        {this.state.order.name}
      </div>
    )
  }
}

1 EventEmitter tên là OrderStore:

import {EventEmitter} from ...
import Dispatcher from ...

class OrderStore extends EventEmitter {
  constructor(Dispater) {
    super()
    
    this.store = {
      orders: null,
      changed_count:  0
    }
    
    this.dispatchToken = Dispatcher.register((action) => {
       if (action.type === "ChangeName") {
         order = _.find(this.store.orders, 'id', action.order.id)
         order.name = "New Name"
         this.store.changed_count++
         
         this.emit("ChangeOrders")
       }
    })
  }
  
  get all() {
    return this.store
  }
  
  addListener(callback) {
    this.on("ChangeOrders", callback)
  }
}

1 Const tên là OrderAction:

import Dispatcher from ...

export const OrderAction = {
  changeName(order) {
    Dispatcher.dispatch({
      type: "ChangeName",
      order: order
    })
  }
}

Tại OrderList ta đã thêm dòng OrderStore.addListener(() => this.setState(OrderStore.all) tại method componentDidMount(), Mỗi khi có thay đổi tại OrrderStore hàm callback lại được gọi để cập nhật orders từ store vào State, do vậy mỗi khi click vào để thay đổi name của OrderDetail tại conponent con thì sẽ cập nhập ngược lại component cha là OrderDetailList.

Cảm ơn và hi vọng bài viết giúp ích trong công việc của bạn.