Learn-Redux

Phương thức dispatch

function dispatch(action, ...args) {
  state = reducer(state, action, args); // reducer xem như callback
  // Tạo state mới từ state cũ, action và các tham số khác.
  // state được thay đổi mới -> store sẽ được update lại, và cần VIEW thay đổi lại.
  render(); // Update lại VIEW
}
function createStore(reducer) {
  let state = reducer(); // Sử dụng closure

  const roots = new Map();

  // Xử lý Render từng hàm component vào root component thành phần tương ứng
  function render(){
    // Vòng lặp qua roots để chuyển ra VIEW
    for(const [root, component] of roots){
      const output = component();
      root.innerHTML = output;
    }

  // Trả về Object gồm các phương thức để xử lý ra View
  return {
    // 1. Phương thức đẩy component và root element tương ứng vào Roots
    attach(component, root){
      roots.set(root,component); // Sử dụng method set của đối tượng Map()
      render(); // Sau khi gán xong sẽ render ra view luôn
    },

    // 2. Lọc các state thích hợp chuyển qua View
    connect(selector = state => state){
      return component => (props, ...args)=>
        component(Object.assign({}, props, selector(state), ...args))
        // Merge các đối tượng vào Object gán vào Object.assign
    },

    // 3. Dispatch : Thao tác người dùng tác động trên VIEW sẽ đẩy hành động
    dispatch(action,...args){
      state = reducer(state, action, args);
      render(); // Update lại VIEW
    }
  }
}

Xử lý Render

2.3 Hàm dispatch

<button onclick="dispatch('ADD', 'Porsche')">Add car</button>
dispatch(action, ...args) {
    state = reducer(state, action, args)
    render()
}
case 'ADD':
  const [newCar] = args
  return {
      ...state,
      cars: [...state.cars, newCar]
  }
function render() {
  for (const [root, component] of roots) {
    // component là những thành phần chứa view.
    const output = component();
    root.innerHTML = output;
  }
}
connect((selector = (state) => state));
state = reducer(state, action, args);