Thứ Hai, 23 tháng 12, 2019

React - Hook

import React, { useEffect, useRef, useContext, useState } from “react”;
import { useDispatch, useSelector } from “react-redux”;
import PropTypes from “prop-types”;
import styled from “styled-components”;
//img
//ic
//data
//action
//component
//styled
const Bound = styled.div``;//========================MAIN COMPONENT==========================
const ComponentName = props => { //======================Props===================================
//=====>Props Data
//=====>Props Function
const { propss } = props;
//======>Props Style
//======================State===================================
const [stateItem, setStateItem] = useState(“”);
//======================Redux===================================
//=====>Redux Action
const dispatch = useDispatch();
//=====>Redux Props
// const { itemReducer } = useSelector(state => ({
// item: state.itemReducer
// }));
//======================REF====================================
const nameRef = React.useRef(null);
//======================Variable================================
const variable = “”;
//======================Function=================================
const _myFunction = argument => {};
//======================Lifecycle Hook===========================
//=====================Render Main Component=====================
return <Bound>CONTENT COMPONENT</Bound>;
};
export default React.memo(ComponentName); //Avoid re-render === shouldComponentUpdate//================================Convert Lifecycle Hook======================================================
//[] === ComponentDidMount (run when init component)
// useEffect(() => {
// console.log(“I just mounted!“);
// }, []);
//return closure function === ComponentWillUnmount
// useEffect(() => {
// return () => console.log(“I am unmounting”);
// }, []);
//[props.count] === ComponentWillrecieveProp\ComponentDidUpdate (run when argument change)
// useEffect(() => {
// console.log(“count changed”, props.count);
// }, [props.count]);
//Empty === ComponentDidUpdate(allow run )
// useEffect(() => {
// console.log(“Just updated...“);
// });ComponentName.propTypes = {
propsItem: PropTypes.string.isRequired
};
ComponentName.defaultProps = {
propsItem: “argument”
};

Tìm hiểu thêm về Hook:
https://usehooks.com/

Thứ Tư, 23 tháng 10, 2019

Redux-Saga vs Redux-Thunk


So sánh redux-thunk với redux-saga
- Điểm giống và khác nhau
- Khi nào sử dụng redux-saga để hiệu quả cho dự án
- Ưu điểm vượt trội của redux-saga là gì



Giống nhau gì ?

1. Middleware Một ứng dụng thực tế thường đòi hỏi có những thao tác xử lý cần thời gian để phản hồi ( các thao tác bất đồng bộ lấy dữ liệu từ api hay các thao tác đọc ghi file hay đọc cookie từ trình duyệt, …)
2. Redux (đòi hỏi gì)
Thứ nhất: Các xử lý trong Reducers phải là các hàm đồng bộ và pure, trả về state mới
Thứ hai: Reducers sẽ ko được sử dụng các hàm async vì không được thay đổi global state.
Trong Redux, middleware là một lớp nằm giữa Reducers và Dispatch Action, nó sẽ modify và được gọi trước khi action được dispatch.
Vậy redux-thunk và redux-saga sinh ra để thực hiện động tác middleware

* Side effect là gì??

- Tất cả những xử lý ở REDUCER đều phải là synchronous và pure tức chỉ là xử lý đồng bộ
- Nhưng trong ứng dụng thực tế thì cần nhiều hơn vậy ví dụ như asynchronous (thực hiện một số việc như gọi một hàm AJAX để fetch dữ liệu về nhưng cần đợi kết quả chứ kết quả không trả về ngay được) hoặc là impure (thực hiện lưu, đọc dữ liệu ra bên ngoài như lưu dữ liệu ra ổ cứng hay đọc cookie từ trình duyệt… đều cần đợi kết quả).
Những việc như thế trong lập trình hàm gọi nó là side effects.
--------------------
Khác nhau gì?
a. Generator function : Generator function là function có khả năng hoãn lại quá trình thực thi mà vẫn giữ nguyên được context

- Đơn giản thì generator function là 1 function có khả năng tạm ngưng trước khi hàm kết thúc (khác với pure function khi được gọi sẽ thực thi hết các câu lệnh trong hàm), và có thể tiếp tục chạy tại một thời điểm khác.
- Chính chức năng mới này giúp ta giải quyết được việc bất đồng bộ, hàm sẽ dừng và đợi async chạy xong rồi tiếp tục thực thi.

b. Saga hoạt động như thế nào vậy ?


- Redux-saga tạo ra phần side-effect độc lập với actions và mỗi action tương ứng sẽ có 1 saga tương ứng xử lý.
- Redux saga cung cấp các hàm helper effect
- Các hàm này sẽ trả về một effect object chứa đựng thông tin đặc biệt chỉ dẫn middeware của Redux có thể thực hiện tiếp các hành động khác
- Về tư tưởng thì saga là: Saga =Worker+Watcher
Worker: là 1 hàm làm nhiệm vụ get/fetch data từ api về sau đó dispatch 1 action
Watcher: là 1 hàm nào đó có nhiệm vụ lắng nghe 1 action nào đó ở view và gọi 1 worker tương ứng để xử lý action đó
Một số hàm helper trong redux saga:
  1. takeEvery() : thực thi và trả lại kết quả của mọi actions được gọi.
  2. takeLastest() : có nghĩa là nếu chúng ta thực hiện một loạt các actions, nó sẽ chỉ thực thi và trả lại kết quả của của actions cuối cùng.
  3. take() : tạm dừng cho đến khi nhận được action
  4. put() : dispatch một action.
  5. call(): gọi function. Nếu nó return về một promise, tạm dừng saga cho đến khi promise được giải quyết.
  6. race() : chạy nhiều effect đồng thời, sau đó hủy tất cả nếu một trong số đó kết thúc
c. Saga có ưu/ nhược điểm gì vậy?
Ưu điểm:
-Do tách riêng side-effect ra khỏi action nên việc testing là dễ dàng hơn Redux-Thunk.
- Giữ cho action pure synchronos theo chuẩn redux và loại bỏ hoàn toàn callback theo javascript truyền thống.
Nhược điểm
- Function ko viết được dạng arrow-function.
- Phải hiểu về Generator function và các khái niệm trong saga pattern
4. Redux-Thunk là gì và hoạt động như thế nào ?

a. Thunk là gì?
Thunk là 1 function mà nó khác biệt những function bình thường là thay vì return trực tiếp kết quả thì thunk lại return ra 1 function và trong function đó làm tiếp một vài nhiệm vụ nữa sau đó mới return ra kết quả cuối cùng.
b. Redux-Thunk là sao?
- Trong redux-thunk áp dụng nguyên lý của Thunk để return 1 function có 2 tham số getState và dispatch 2 tham số này chính là 2 thuộc tính của store trong Redux
- Bằng cách này thì redux-thunk cho phép ta tạo ra side-effect ( như fetch data, delay request …) sau đó mới dispatch 1 action 
c. Tổng quan và nhận xét chung về redux-thunk
Nhìn chung redux-thunk là khá dễ hiểu, dễ code nhưng chưa thật sự mạnh mẽ trong nhiều tình huống như sau:
- Tạm dừng 1 Request hoặc hủy request khi đang call api.- Bài toán click vào Button để fetch data nếu click liên tục nhưng chỉ lấy lần click sau cùng?
- Bài toán Auto-Search, tự động hiển thị kết quả sau mỗi lần gõ text, để tránh request server liên tục thì yêu cầu sau 1 khoảng thời gian ví dụ 2s thì mới thực hiện request, hoặc gõ từ khóa mà nó trùng với từ khóa trước thì ko request lại.
- Tự động Retry request một vài lần khi có sự cố ví dụ như sự cố mạng xảy ra?
và còn nhiều yêu cầu khác phức tạp hơn nữa...


Thứ Năm, 17 tháng 10, 2019

NodeJS

I. CÀI ĐẶT NODE
1. Tài vài cài đặt tại : https://nodejs.org/en/download/
2. Tải và cài git-scm : https://git-scm.com/
3. Kiểm tra trên terminal lệnh: node -v
và npm lệnh: npm -v

II. V8 Engine là gì?
- Máy tính không hiểu ngôn ngữ Javascript
- Javascript Engine dịch Javascript để máy tính hiểu - mã máy (magine code)
- Machine Code là (JavaScript --> C++ --> Asembly Language --> Machine Code)
Vì vậy:
- Node.js được viết trên nền C++
- Trái tim của Node là V8 engine
- V8 chuyển JS thành magine code


III. Hàm cơ bản trong Node.js
1. Tạo file
- Tạo file app.js
- Viết lệnh giống JS
- Chạy lệnh : node app.js trên Terminal
2 Normal Func -- GỌi thoải mái bất cứ đâu trong source
function sayHello(){
    console.log('Hello');
}
sayHello()
3. Function Expression
    sayGo() //  -- TypeError: sayGo is not a function
lỗi sayGo() chưa được khai báo khi gọi


    var sayGo = function(){
        console.log('Go home');
        
    }


4. Hàm expression được thực thi trong hàm Normal
VD
    function callFunc(func){
        func() // Hàm được gọi lại là hàm Expression hoặc 1 hàm Normal
    }
    var hayYo = function(){
        console.log('Hay Yo');
    }
    var biCreate = function(){
        console.log('bibiCreate');
    }
    callFunc(hayYo)
    callFunc(biCreate)
    callFunc(sayHello)


IV. Module và Require


file app.js
// Import 1 module ở 1 file khác dùng hàm require("./đường dẫn")
var dem =  require("./md"

console.log('ABC -- hihi');

console.log(dem(['1',1,2])); // --> gọi và sử dụng hàm dem()
console.log(dem([0,0,0,0,0,0,0,0]));

file md.js

var dem = function(arr){
    return "There are " + arr.length + ' element in Array'
}
// Export cả module dưới dạng hàm
module.exports = dem

V.  Module Patterns  để import nhiều hàm trong 1 file
1. Cách 1












file app.js
// Import 1 module ở 1 file khác dùng hàm require("./đường dẫn")
var test =  require("./pt"

console.log('ABC -- hihi');

console.log(test.demt(['1',1,2])); // --> gọi và sử dụng hàm dem()
console.log(test.tinht(1,2)); // --> gọi và sử dụng hàm tinh()
console.log(test.chaot()); // --> gọi và sử dụng hàm chao()
file pt.js
var dem = function(arr){
    return "There are " + arr.length + ' element in Array'
}
var  tinh = function(a,b){
    return `Sum is ${a+b}`
}
var chao = function(){
    console.log('Hello bibi');
}
// module.exports.(ten muon export) = name function express
module.exports.demt = dem
module.exports.tinht = tinh
module.exports.chaot = chao

2. Cách 2

3. Cách 3

** Hướng đối tượng v2


VI. (sự kiện) on() và emit()  --- Nghe vs Nói
Hàm khởi tạo require('events')
// import modules "events"
// b1. Khởi tạo module trong file bởi  :  require('events')
var sukien = require('events')
// tạo EventEmiter
// b2. Tạo 1 EventEmiter 
var test = new sukien.EventEmitter()
//b4. Tạo hàm Nghe với
// ten_bien.on('key',function(evt){Lam_gi_o_day})
test.on('someKey'function(mgs){ // Nghe
    console.log(mgs);
})
// b3. Tạo key và dữ liệu cho sự kiện nói bởi
// ten_bien.emit('key', data_tranfer)
test.emit('someKey','Hello Mint Mint'// Nói
ví dụ 2:
Khởi tạo  require('util')
// import modules "events"
var sukien = require('events')
var hamchinh = require('util')

// tao Function Express
var Person = function(name){
    this.name = name
}
// inherits(a,b)  : hàm kế thừa của hàm a, b là sự khởi tạo
hamchinh.inherits(Person,sukien.EventEmitter)
var sky = new Person('toan')
var black = new Person('hai')
var deal = new Person('trung')

var people = [sky,black,deal]
people.forEach(function(person){
    person.on('talk'function(msg){
        console.log(person.name + ' Said that: ' +msg);
        
    })
})
sky.emit('talk''Hello')
black.emit('talk''Hello vbbjs')
deal.emit('talk''Hello xbcx')
// console.log(test);
// toan Said that: Hello
// hai Said that: Hello vbbjs
// trung Said that: Hello xbcx

VII. Đọc và Ghi file trong Node.js
Hàm khởi tạo require('fs')
var file = require('fs'// khởi tạo file để Đọc/Ghi
console.log('Bắt đầu');

// Hàm đọc file đồng bộ readFileSync('ten_file',kieu_utf8)
var readfile = file.readFileSync('test.txt','utf8')
console.log(readfile);

// Hàm viết/ghi file đồng bộ writeFileSync('ten_file',noi_dung)
var writeFile = file.writeFileSync('hiihi.js','come on babe')

// Hàm Đọc và Ghi file bất đồng bộ :::
// Cấu trúc readFile(file,type,callback) --> file:ten_file,type:type_data,callback:func được thực hiện sau cùng
var readFileNotSync = file.readFile('test.txt','utf8',function(err,d){
    if(trueconsole.log('dung:' + d); // kết quả này đc thực hiện sau cùng
    else return 'sai'
})
console.log('Kết thúc');
// Bắt đầu
// Hello every one !
// Kết thúc
// dung:Hello every one !

VIII. Tạo/Xóa thư mục Folder/File
var file = require('fs')
// require('fs') : khai báo trình chuẩn bị quản lý file
file.unlink('testWrite.txt'// Lệnh xóa file nào đó cùng cấp unlink.('ten_file')

file.mkdirSync('testC'// -- Tạo 1 folder dùng hàm mkdirSync()

file.rmdirSync('testC'// -- Xóa 1 folder dùng hàm rmdirSync()

file.mkdir('public'function(){ // -- Tạo file public
    file.readFile('test.txt','utf8',function(err,data){ // -- đọc file test.txt
        console.log(err,data);
        file.writeFileSync('./public/results.txt'data// ghi nội dung data vào file results trong thư mục public
    })
})

IX. Hoạt động Server trong NodeJS
1.Phương thức giao tiếp giữa Client và Server
Khách: gửi request lên Server
Server: trả dữ liệu về cho Client


2. Socket . dùng IP của client và server,
Socket gồm nhiều các gói nhỏ để thực hiện các giao thức

3. TCP

3. Port, địa chỉ IP của máy. Lắng nghe các giao thức của Soket

* Socket.io
  • Là một module của NodeJs
  • Được xây dựng nhằm mục đích tạo ra real time NodeJS application. Socket.io cung cấp cho lập trình viên các đặc trưng như event, room và tự động phục hồi lại kết nối.
  • Khi chúng ta include Socket.io module vào trong ứng dụng của mình nó sẽ cung cấp cho chúng ta hai object đó là: socket server quản lý functionality phía server và socket client điều khiển funtionality phía client.
  • Khi client muốn kết nối tới Socket.io server, nó sẽ gửi cho server một “handshake HTTP request”. Server sẽ phân tích request đó với những thông tin cần thiết trong suốt quá trình kết nối. Nó sẽ tìm cấu hình của middleware mà đã được đăng ký với server và thực thi chúng trước khi đưa ra sự kiện kết nối. Khi kết nối thành công thì connection event listener được thực thi, tạo ra một instance mới của socket có thể coi như định danh của client mà mỗi một client kết nối tới sẽ có 1 định danh. Các bạn có thể thấy rõ khi xem hình dưới đây
4. Khởi tạo server đơn giản
Header: cả Client và Server đều cần Header, Header là phần để thêm thông tin mà client ko nhìn thấy


Phần Response Header bao gồm : Content và Status

*** Tạo 1 server Local
Để sử dụng được bất kỳ module nào trong Node.js thì chúng ta cần phải require module đó. Và để require một module trong Node.js chúng ta sử dụng từ khóa require.
 require('http') Khởi tạo module http trong Node


-Bên trong phương thức createServer chứa một phương thức ẩn danh có 2 tham số truyền vào.

  • Tham số thứ nhất: là biến chứa các thông số liên quan đến request mà người dùng gửi lên.
  • Tham số thứ hai là biến chứa các thông số liên quan đến response mà chúng ta muốn trả về client.


var http = require('http'// Khởi tạo module http trong Node
var server = http.createServer(function(req,res){
//thiết lập giá trị server trả về
    res.writeHead(200,{'Content-Type':'text/plain'})
    res.end('Run done!')
}) // Khởi tạo server createServer()
//Khởi tạo server chạy cổng 3333
server.listen(3333,'127.0.0.1')
console.log('chay serrver');

*  Các phương thức và thuộc tính hay dùng trong resquest và response.

- Hàm writeHead() thiết lập kiểu dữ liệu mà server muốn trả về.
// khai báo sử dụng module HTTP var http = require('http'); //Khởi tạo server chạy cổng 8000 http.createServer(function (request, response) { response.writeHead(200, {'Content-Type': 'text/html'}); response.write('Hello world'); response.end(); }).listen(8000);
- Hàm write() Hàm này thiết lập nội dung mà server muốn trả về trình duyệt, nội dung này có thể là text có thể là HTML code.
VD: Trả về một trang HTML có thẻ H1 chứa dòng chữ hello world.

// khai báo sử dụng module HTTP var http = require('http'); //Khởi tạo server chạy cổng 8000 http.createServer(function (request, response) { response.writeHead(200, {'Content-Type': 'text/html'}); response.write('<html>'); response.write('<head>'); response.write('<title>Hello world </title>'); response.write('</head>'); response.write('<body> <h1>Hello world<h1> </body>'); response.write('</html>'); response.end(); }).listen(8000);
- url :  thuộc tính này chứa các paramter trong URL mà client gửi lên server.
VD:
// khai báo sử dụng module HTTP var http = require('http'); //Khởi tạo server chạy cổng 8000 http.createServer(function (request, response) { var param = request.url; response.write(param); response.end(); }).listen(8000);

Lúc này các tiền tố phía sau domain sẽ được hiện ra nếu có: vd http://localhost:8000/toidicode thì url sẽ là /toidicode.

X. Khái niệm Buffer và Streams
Tưởng tượng lượng data bạn sẽ phải chuyển từ server đến client là 1 núi đường, vậy làm sao để có thể làm công việc này 1 cách nhanh nhất

Chúng ta hãy cắt nhỏ Data đó ra và xếp chúng vào những chiếc xe Buffer đến lúc đầy và chuyển chúng đi nơi khác
// Buffers là không gian lưu trữ tạm những data nhỏ, nó sẽ chuyển đến 1 nơi khác khi nó đầy


VD:

Stream giống nhưng con đường thể hiện luồng đi của những chiếc xe
// Streams là luồng dữ liệu mà data được chuyển đi, stream quản lý luồng data này. 
Làm tăng hiệu xuất chuyển dữ liệu


// Vì vậy Nodejs có thể Realtime

1. Đọc/Ghi dữ liệu bằng Realable
var file = require('fs')
// Hàm createReadStream() Tạo 1 luồng Stream với data là file readMe.txt, định dạng kiểu utf8.
//--> Nếu bỏ encoding sẽ thấy được các Buffer
var docluong = file.createReadStream(__dirname + '/readMe.txt', {encoding:'utf8'})
var ghiluong = file.createWriteStream(__dirname + '/writeMe.txt') // Hàm createWriteStream() để ghi
docluong.on('data'function(chunk){
    console.log('Doc luong nao: ');
    console.log(chunk);
ghiluong.write(chunk); //--> sau khi đọc xong thì ghi
})

2. Khái niệm Pipe
Pipe như khúc cua, đẩy dữ liệu sang ống khác
VD:
var http = require('http')
var file = require('fs')
var server = http.createServer(function(rep,res){
    res.writeHead(200, {'ContentType':'text/plain'}) //--> Đổi thành 'text/html' [Nếu là file html]
    var docluong = file.createReadStream(__dirname + '/readMe.txt','utf8') //--> đổi file nhúng là
index.html
    docluong.pipe(res) // Chuyển dữ liệu sang luồng mới
})
server.listen(8808,'127.0.0.1')
console.log('Server running on port 8808');
Mở port: 127.0.0.1:8808 thì thấy dữ liệu file readMe.txt hiện lên brower

XI. Truyền dữ liệu kiểu JSON
var http = require('http')
var server = http.createServer(function(rep,res){
    res.writeHead(200, {'ContentType':'application/json'}) // định dạng kiểu dữ liệu trả về
 'application/json' viết vào Header
    var obj = {
        name: 'Trương Văn Toàn',
        job: 'developer',
        age: 21,
        home: "Hai Duong"
    }
    res.end(JSON.stringify(obj)) /***/ responsive - trả về đối tượng kiểu JSON
})
server.listen(8808,'127.0.0.1'// server lắng nghe cổng http://127.0.0.1:8808/
console.log('Server running on port 8808');

XII. Điều hướng
var http = require('http')
var file = require('fs')
var server = http.createServer(function (reqres) {
    console.log('nguoi dung yeu cau link: ' + req.url);
    // Giải pháp điều hường link url người dùng
    if (req.url === '/' || req.url === '/home') {
        res.writeHead(200, { 'ContentType': 'application/json' })
        file.createReadStream(__dirname + '/index.html''utf8').pipe(res)
    } else if (req.url === '/login') {
        res.writeHead(200, { 'ContentType': 'text/html' })
        file.createReadStream(__dirname + '/login.html''utf8').pipe(res)
    } else if (req.url === '/api/re') {
        var register = [
            { name: 'bibi'age: 12job: 'gamer' },
            { name: 'chim se'age: 2job: 'gamer' },
            { name: 'z'age: 1job: 'gamer' }
        ]
        res.writeHead(200, { 'ContentType': 'application/json' })
        res.end(JSON.stringify(register))
    } else if (req.url === '/404') {
        res.writeHead(200, { 'ContentType': 'text/html' })
        file.createReadStream(__dirname + '/404.html''utf8').pipe(res)
    }
})
server.listen(8808'127.0.0.1'// server lắng nghe cổng http://127.0.0.1:8808/
console.log('Server running on port 8808');

c








c


c