Learn-Redux

Phương thức connect


function connect(selector = state => state){
  ...
}
function connect(selector = (state) => state) {
  // selector chọn các thành phần state, bình thường sẽ lấy tất cả state
  return (component) =>
    (props, ...args) =>
      component(Object.assign({}, props, selector(state), ...args));
}
function connect(selector = (state) => state) {
  return (component) => {
    return (props, ...args) => {
      return component(Object.assign({}, props, selector(state), ...args));
    };
  };
}
function connect(selector = state => state){
  return component => (props, ...args) =>
    component(Object.assign({}, props, selector(state), ...args))
},
connect(selector = (state) => state) {
    return (component) =>
      (props,args) => //props,args sẽ được nhận khi có đối số ở lần call thứ 3 bên dưới
            component(Object.assign({}, props, selector(state), ...args));
}

// Khi sử dụng method connect
connect()(App)() => App(Object.assign({}, undefined, selector(state), undefined);

Giải thích đoạn return component này:

Return component

function helloWorld(str) {
  return console.log(str + ' Javascript!');
}

function connect() {
  return (component) => {
    console.log('Hello World');
    return component('Xin chào');
  };
}

const connector = connect();
connector(helloWorld);
connect()(helloWorld); // Giống đoạn code trên

// Hello World
// Xin chào Javascript!

Các bạn có thể biến nó thành đoạn code sau:

connect(selector = state => state){
    return component => {
      // Trả về lần 1
        return (props, ...args) => {
          // Trả về lần 2
          return component(Object.assign({}, props, selector(state), ...args)) // Trả về lần 3
        }
    }
}
const connector = connect();
export default connector(App);

Chính vì thế khi gọi

attach(App, document.getElementById('root'))
=>
attach(component, root) {
    roots.set(root, component)
    render()
}
const output = component();
const output = connector(App)();
    // let state = reducer();
    function 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
    },
    /**
    const connector = connect(state=>({
      car: state.car[0],
      cars: state.cars
    }));

    function app({pops}){
      return html `
      <ul>
        ${cars.map(car=>`<li>${car}</li>`)}
      </ul>
      `
    }
    */
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
    },
    ...
  }
}

2.2 Hàm connect là hàm đẩy dữ liệu từ store ngược vào view.

import { connect } from '../store.js';
const connector = connect();
export default connector(App)

connect(selector = state => state) {
    return component => (props, ...args) =>
        component(Object.assign({}, props, selector(state), ...args))
},

HAY:

connect(selector = state => state){
  return component => {
    return (props, ...args) => {
      return component(Object.assign({}, props, selector(state), ...args))
    }
  }
}

==> connect chạy sẽ return lại 1 arrow function, nhận đối số là 1 component.

return component(Object.assign({}, props, selector(state), ...args));
Object.assign({}, props, selector(state), ...args);
return html`
  <ul>
    ${cars.map((car) => `<li>${car}</li>`)}
  </ul>

  <button onclick="dispatch('ADD', 'Porsche')">Add car</button>
`;