Skip to main content

· 4 min read
Vũ Anh Tú

1. OpenAI

Open AI là một trong những công ty nghiên cứu và triển khai trí tuệ nhân tạo hàng đầu thế giới. Công ty này tập trung vào việc phát triển các mô hình AI để giải quyết các vấn đề thực tế và mang lại giá trị cho con người. Các mô hình AI của Open AI được tập trung vào các lĩnh vực như ngôn ngữ tự nhiên, hình ảnh, âm thanh, và code lập trình.

· One min read
Vũ Anh Tú

How to create API service

const Header = {
token: LocalStorage.getItem("token"),
};

const PATH_BASE = "";

class DynamicAPI {
constructor() {
this.header = Header;
this.pathBase = PATH_BASE
}

request = ({path, method, body}) => {
return fetch(this.pathBase + path, {
method: method,
headers: this.header,
body: body
}).then((response) => {
// if response success => return response
// else if 401 => logout
// else if 404 => redirect Not Found
// else if 409 => throw Error
// ....
})
};

get = ({path}) => {
return this.request({path, method: "GET", body: null})
};

post = ({path, body}) => {

}
/*same for post, delete and put*/
}

export default new DynamicAPI();

const AuthService = {
login: async (email, password) => {
const res = await DynamicAPI.post({path: "/login", body: {email, password}})
// LocalStorage.setItem("token", token)
// LocalStorage.setItem("user", user)
},

logout: () => {

}
};

const APIService = {
getListStaff: () => {
return DynamicAPI.get({path: '/staff'})
}
};

· 2 min read
Vũ Anh Tú

Ý tưởng chính của component

  • Component nên được tạo nên từ các thành phần nhỏ nhất là các component nhỏ hơn nữa được custom từ DOM của HTML, tuy nhiên được custom theo từng UI Ví dụ dưới đây là component được custom từ input: Ở đây sự dụng component custom như là một Node của HTML tuy nhiên có thể style theo từ dự án
import React from "react";

const Input = (props) => {
return (
<>
<input placeholder="Custom input" {...props}/>
</>
)
}

export default Input;

Các cách để tạo ra một basis

1. Sử dựng Style component
  • Có thể dựng component, truyền props để xây dựng UI
import styled from 'style-component'

const Button = styled.button`
/* Adapt the colors based on primary prop */
background: ${props => props.primary ? "palevioletred" : "white"};
color: ${props => props.primary ? "white" : "palevioletred"};

font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border: 2px solid palevioletred;
border-radius: 3px;
`;

render(
<div>
<Button>Normal</Button>
<Button primary>Primary</Button>
</div>
);
2. Sử dụng REF => Can thiệp sâu hơn vào API của DOM
  • Như là ở một article nào đó tôi đã nói kĩ về refs, và các cách để ứng dụng refs vào một component. Ứng dụng của refs là rất thực tiễn cho các component nhỏ, cần can thiệp sâu vào các API của element DOM ví dụ như: focus(), blur(), click(), select(), setSelectionRange(), setRangeText() setCustomValidity(), checkValidity(), reportValidity()

Create component

export default class InputClass extends React.Component {
state = {
test: "test"
}
showLog = () => {
console.log("show log");
};
render() {
return (
<>
<div>Class input component</div>
<div>Test: {this.state.test}</div>
<input placeholder="class input" />
</>
);
}
}

const InputRef = React.forwardRef((props, ref) => (

<>
<div>Custom input component using forward re</div>
<input placeholder="custom ref input" ref={ref} {...props}/>
</>

))


>Using
```javascript
function App() {
let customRefInput = React.createRef();
let classInput = React.createRef();
const [inputValue, setInputValue] = useState("");
return (
<div className="App">
<h1>Hello React 17</h1>
<h2>Start learing REF react</h2>
<Input
value={inputValue}
onChange={e => setInputValue(e.target.value)}
ref={node => console.log("input 1", node)}
/>
<InputRef ref={node => (customRefInput = node)} />
<InputClass ref={node => (classInput = node)} />
<div>
<button onClick={() => customRefInput.focus()}>Focus</button>
<button onClick={() => customRefInput.blur()}>Blur</button>
<button onClick={() => classInput.setState({ test: "test" })}>
Reset state
</button>
<button onClick={() => classInput.setState({ test: "Change test" })}>
Set state
</button>
</div>
</div>
);
}

· 4 min read
Vũ Anh Tú

Refs là gì:

  • Theo react official: React supports a special attribute that you can attach to any component (DOM node and component). The ref attribute can be an object created by React.createRef() function or a callback function, or a string (in legacy API). When the ref attribute is a callback function, the function receives the underlying DOM element or class instance (depending on the type of element) as its argument. This allows you to have direct access to the DOM element or component instance. Use refs sparingly. If you find yourself often using refs to “make things happen” in your app, consider getting more familiar with top-down data flow.
  • Refs là một thuộc tính đặc biệt có thể attach vào bất kể một component nào (DOM node and component), thuộc tính ref có thể được tạo ra bằng React.createRef(), hoặc dùng function (node) => refName = node, hoặc đơn giản là string

    1. String refs: Là cách cũ nhất để tạo ra một refs và sẽ bị loại bỏ trong tương lai

    // String
    export default class index extends React.Component {
    constructor() {
    super();
    this.state = {sayings: "" };
    }
    update(e) {
    this.setState({sayings: this.refs.input.value});
    }

    render() {
    return (
    <div>
    Bob says <input type="text" ref="btalks" onChange={this.update.bind(this)} />
    {this.state.sayings}
    </div>
    );
    }
    }

    If you’re currently using this.refs.textInput to access refs, we recommend using either the callback pattern or the createRef API instead.

    2. Callback refs

    class MyComponent extends React.Component {
    constructor(props) {
    super(props);
    this.state = { uppercase: false };
    }

    toggleInputCase = () => {
    const isUpper = this.state.uppercase;
    // Accessing the ref using this.inputField
    const value = this.inputField.value;
    this.inputField.value =
    isUpper
    ? value.toLowerCase()
    : value.toUpperCase();
    this.setState({ uppercase: !isUpper });
    }
    render() {
    return (
    <div>
    {/* Creating a callback ref and storing it in this.inputField */}
    <input type="text" ref={elem => this.inputField = elem} />
    <button type="button" onClick={this.toggleInputCase}>
    Toggle Case
    </button>
    </div>
    );
    }

    }

    3. Using React.createRef()

    class MyComponent extends React.Component {
    constructor(props) {
    super(props);
    this.myRef = React.createRef();
    }
    render() {
    return <div ref={this.myRef} />;
    }
    }
 

#### 4. Some technical of Refs
##### a. Forward refs:
* Là kĩ thuật tự động truyền ref qua một component => đến một trong các component con của nó
```javascript
function FancyButton(props) {
return (
<button className="FancyButton" {...props}>
{props.children}
</button>
);
}
  • Xét vd trên: đây là các thông thường để tạo một custom component từ element, có thể lấy được hết các props từ cha đến thằng input nằm bên trong, tuy nhiên những API như focus(), blur(), click(), select(), setSelectionRange(), setRangeText() setCustomValidity(), checkValidity(), reportValidity() thì forward ref sẽ giải quyết đc vấn đề này:
import React from 'react'

const InputRef = React.forwardRef((props, ref) => (
<>
<input placeholder="custom ref input" ref={ref} {...props}/>
</>
))

export default InputRef

// Using
function App() {
let customRefInput = React.createRef();
const [inputValue, setInputValue] = useState("");
return (
<div className="App">
<h1>Hello React 17</h1>
<h2>Start learing REF react</h2>
<div>Custom input component</div>
<Input value={inputValue} onChange={e => setInputValue(e.target.value)} />
<div>Custom input component using forward ref</div>
<InputRef ref={node => (customRefInput = node)} />
<div>
{/*Click button to focus ref input */}
<button onClick={() => customRefInput.focus()}>Focus</button>
</div>
</div>
);
}
b. Refs for class component
  • Mỗi class component (function component không có) cũng có thuộc tính ref, ref trỏ đến đối tượng (instance) được tạo ra từ class component Từ đây có thể access vào các method có sẵn của component được gán ref cũng như các method tự định nghĩa, ví dự trong tình huống này là method showLog

export default class InputClass extends React.Component {
showLog = () => {
console.log("show log");
};
render() {
return (
<>
<input placeholder="class input" />
</>
);
}
}


function App() {
let customRefInput = React.createRef();
let customInput = React.createRef();
const [inputValue, setInputValue] = useState("");
return (
<div className="App">
<h1>Hello React 17</h1>
<h2>Start learing REF react</h2>
<Input
value={inputValue}
onChange={e => setInputValue(e.target.value)}
// Không được show lo
ref={node => console.log("input 1", node)}
/>
<InputRef ref={node => console.log("input 2", node)} />
<InputClass ref={node => console.log("input 3", node)}/>
</div>
);
}
  • Và đây là implememt
function App() {
let customRefInput = React.createRef();
let classInput = React.createRef();
const [inputValue, setInputValue] = useState("");
return (
<div className="App">
<h1>Hello React 17</h1>
<h2>Start learing REF react</h2>
<Input
value={inputValue}
onChange={e => setInputValue(e.target.value)}
ref={node => console.log("input 1", node)}
/>
<InputRef ref={node => (customRefInput = node)} />
<InputClass ref={node => (classInput = node)} />
<div>
<button onClick={() => customRefInput.focus()}>Focus</button>
<button onClick={() => customRefInput.blur()}>Blur</button>
<button onClick={() => classInput.setState({ test: "test" })}>
Reset state
</button>
<button onClick={() => classInput.setState({ test: "Change test" })}>
Set state
</button>
</div>
</div>
);
}

· 4 min read
Vũ Anh Tú

Introduction Observation state management solution:

  • Lấy cảm hứng từ ý tưởng Observer pattern cùng việc học hỏi theo một trainer(FOZG) của mình tại FPT đã viết một công cụ có thể làm việc như là một thư viện quản lí trạng thái.
  • Trong dự án tôi sử dụng 2 pattern chính là Observer PatternSingleton Pattern, trong một bài viết khác mình sẽ đề cấp đến một số pattern được sử dụng rất nhiều trong các dự án Javascript

Observer Pattern:

alt text

  • Như được biểu diễn trong sơ đồ UML, các đối tượng cần thiết là subject, observer và các đối tượng cụ thể. Subject có chứa tham chiếu đến các observers cụ thể để thông báo cho bất kỳ thay đổi. Đối tượng Observer là một lớp trừu tượng cho phép các observers cụ thể thực hiện phương thức thông báo
let Subject = function() {
// Một stack các observers subscribe Subject
this.observers = [];

return {
subscribeObserver: function(observer) {
this.observers.push(observer);
},
unsubscribeObserver: function(observer) {
let index = this.observers.indexOf(observer);
if(index > -1) {
this.observers.splice(index, 1);
}
},
notifyObserver: function(observer) {
let index = this.observers.indexOf(observer);
if(index > -1) {
this.observers[index].notify(index);
}
},
notifyAllObservers: function() {
for(let i = 0; i < this.observers.length; i++){
this.observers[i].notify(i);
};
}
};
};

let Observer = function() {
return {
notify: function(index) {
console.log("Observer " + index + " is notified!");
}
}
}

let subject = new Subject();

let observer1 = new Observer();
let observer2 = new Observer();
let observer3 = new Observer();
let observer4 = new Observer();

subject.subscribeObserver(observer1);
subject.subscribeObserver(observer2);
subject.subscribeObserver(observer3);
subject.subscribeObserver(observer4);

subject.notifyObserver(observer2); // Observer 2 is notified!

subject.notifyAllObservers();
// Observer 1 is notified!
// Observer 2 is notified!
// Observer 3 is notified!
// Observer 4 is notified!
  • Tư tưởng chính: ta xây dựng một nơi quản lí state tập trung của cả dự án gọi là Store, tại đây dự liệu sẽ được cập nhật => báo cho các component subscribe Store biết là đã có sự thay đổi store và hãy render lại đi (đã có dữ liệu mới rồi)

  • Implement thế nào? Từ ý tưởng và khi implement là cả môt sự khác biết rất lớn:

  1. Đầu tiên là vấn đề Store (Ở đây là ứng với Subject): Nơi lưu trữ dữ liệu, subscribe component và update dữ liệu Nhưng mà vấn đề ở chỗ là không thể cứ component nào cũng tạo ra một Store được vì như thế còn gì là quản lí tập trung nữa. Điều này làm ta phải nghĩ ngay đến Singleton Pattern :)))) Khó càng thêm khó => Lại thêm một pattern nữa mình băn khoăn (Xem định nghĩa ở dưới nhé) Có thể hiểu là mình cần phải tạo một object (đóng vai trò như là Singleton), tạo một lần dùng mãi mãi :)))) Tạm thời tắc tịt ở đây !!!

  2. Bây là vấn đề Observer: Cái gì là đóng vai trò thông báo cho component biết khi nào cần phải render lại ???. Câu trả lời là: hàm setState của HOC chứa component => Vì khi hàm setState này được trigger thì component subscribe (HOC) sẽ được render lại => Component chính được render lại

  3. Ngon rồi, đã clear hơn một chút về phần subscribe và render lại => Tuy nhiên vấn đề 1 thì còn nan giải. Vậy là cần phải tạo một instance của Store tổng để import vào HOC => Một cách để tạo ra Singleton.

Nhưng mình đang cần phải tạo ra nhiều Store để phục vụ các ứng dựng rỉêng => Giống redux nên thay vì tạo singleton là Store ta sẽ tạo singleton là các Observation chứ hàm connect HOC với component

Chi tiết code xem tại đây: https://github.com/vuanhtu1993/observation-state

Singleton Pattern

· 2 min read
Vũ Anh Tú

3 steps to create React app from nothing

Step 1. npm init

  • Ở bước này ta tạo được một môi trường để quản lí thu viện cũng như source code của dự án
  • Được biết là React là một thư viện để tạo giao diện (UI) được chia nhỏ thành các component bằng code JS (Dùng JSX để viết giao diện)
  • ReactDOM Là thư viện được tách ra từ React core => mục đích nhằm tách biệt phần tạo giao diện với phần giao tiếp với DOM ReactDOM là lớp liên kết giữa ReactDOM, VD: như muốn hiện thị component React vào một DOM nào đó ta dùng
ReactDOM.render(<h1>Hello, world!</h1>,document.getElementById('root'))

// hoặc để tìm DOM
ReactDOM.findDOMNode()
  • React-router-dom Cơ bản React là thư viện để tạo UI cho ứng dụng nên thực chất nó không có Router, khi đó để có thẻ điều hướng trên một ứng dụng React ta cần dùng thư viện này Bài viết chi tiết về React-router-dom sẽ được nói trong một bài viết khác

  • webpack

Step 2. Install react react-dom react-router-dom webpack

  • webpack: là thư viện để tạo ra bundle file từ các file đầu vào js, css, resource ...
  • webpack-cli: Từ bản v4 đươc chia ra từ webpack core, dùng để chạy webpack bằng CLI, phù hợp với production
  • webpack-dev-server: thực hiện hot reload khi có bất kì thay đổi nào từ file đầu vào. Phù hợp với qúa trình development
Triết lí của webpack.
  1. Mọi thứ đều là module: tất cả các file html, css, js, images... đều được webpack coi là một module. Từ đó hoàn toàn có thể export và import nó ở bất cứ chỗ nào để dùng.
  2. Chỉ load nhưng thứ cần và load khi cần thiết: Khi file bundle trở nên quá lớn thì việc client load sẽ trở nên khó khăn và ảnh hưởng đến trải nghiệm. Như vậy webpack có một số cơ chế để tách nhỏ file bundle thành nhiều file ứng với mục đích khác nhau.

Link ref source pure react: https://github.com/vuanhtu1993/observation-state

· 2 min read

Step 1: Install ZSH

  • ZSH (Z Shell) là một Unix shell cái mà được build on top của bash (shell mặc định của mac) và thêm một số tính năng khác
brew install zsh

Step 2: Install Oh My Zsh

  • Oh my Zsh là một framework cho việc quản lí cấu hình zsh. Ở đấy có thể tuỳ chỉnh rất nhiều thứ trong đó có theme của terminal
sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"

Step 3: Install Powerline fonts

  • Là một bộ font được hỗ trợ các kí tự đặc biệt cho terminal
git clone https://github.com/powerline/fonts.git --depth=1
cd fonts
./install.sh
cd ..
rm -rf fonts

Step 4: Change theme and font

Change theme: mở terminal ở thư mục ~

vim .zshrc

Search từ khoá ZSH_THEME="theme name", thay thế bằng ZSH_THEME="default"

ZSH_THEME="agnoster"

Lưu ý:

  • Lúc này khi reset terminal theme đã được apply nhưng mà lỗi font :(
  • Có thể thay rất nhiều theme khác nhau, các theme này đã dược define mặc định trong khi cài Oh my

Change font and color of font Open terminal lên > Terminal > Preference > Profile > Font > Change : chọn Rotobo Mono for Powerline Thay đổi màu từ mặc định cho hợp với style và cá tính của bạn trong Profile > ANSI color

Thế là done rồi :)

· 2 min read

Technique 1 : Object.entries

let obj = {
key1: "value1",
key2: "value2",
key3: "value3"
}

Object.entries(obj)
//0: (2) ["key1", "value1"]
//1: (2) ["key2", "value2"]
//2: (2) ["key3", "value3"]

Object.entries(obj).forEach(entry => {
let key = entry[0];
let value = entry[1];
//use key and value here
});

Technique 2 : Object.keys

let obj = {
key1: "value1",
key2: "value2",
key3: "value3"
}

Object.keys(obj) // return array of object key

Object.keys(obj).forEach(key => {
let value = obj[key];
//use key and value here
});

Technique 3 : Object.values

let obj = {
key1: "value1",
key2: "value2",
key3: "value3"
}

Object.values(obj) // return array of object value

Object.values(obj).forEach(value => {
//use value here
});

Technique 4 : for...in loop

let obj = {
key1: "value1",
key2: "value2",
key3: "value3"
}

for (const key in obj) {
if (obj.hasOwnProperty(key)) {
//no a property from prototype chain
}else{
//property from protytpe chain
}
}

Technique 5 : Object.getOwnPropertyNames

  • Like the for ... in technique but dont need to use hasOwnProperty build in method
let obj = {
key1: "value1",
key2: "value2",
key3: "value3"
}

Object.getOwnPropertyNames(obj).forEach(key => {
let value = obj[key];
//use key and value here
});

· One min read
Vũ Anh Tú

Anaconda common command

  1. conda env list : lists all environments
  2. source activate env name : activate an environment
  3. source deactivate: deactivate an environment
  4. conda list : list all packages installed
  5. conda create --name env name python=3 astroid babel : create new environment, specify version of python, and install packages
  6. WINDOWS NOTE: SOURCE is not recognized. When deactivating and activating in the anaconda command prompt, skip 'source' and just type 'deactivate' or 'activate' depending on what you are trying to do.
  7. conda env export > environment.yml: export conda environment requirements list to a file

Apply anaconda env into PyCharm

  • Mỗi một dự án đều cần được bọc bởi interpreter để lấy các thư viện ra và sử dụng từ trong interpreter đó. Nhiệm vụ bây là thay đổi interpreter măc định (môi trường máy tính global).
Bước 1: tạo interpreter bằng anaconda
  • Có thể tạo interpreter environment bằng conda create --name <env name> hoặc tạo bằng GUI của pyCharm
Bước 2: Adđ interpreter vào Project interpreter

a. Project interpreter => Add interpreter => Existing Environment b. Pick anaconda3/envs/interpreter name/bin/python => Apply