Component phần 6: Tổng kết và hệ thống hóa lại về UI Builder, Web Component và React
Fonts, Sizes và Colors
Vì chúng ta sẽ làm việc trực tiếp trên Wordpress + Elemetor nên bước này cả 3 sẽ giống nhau:
Vào Site settings và cài đặt Global Colors để dùng cho Elementor
Tạo global style trong Custom CSS để dùng CSS variable cho Web Component và React (có thể dùng inspect để check CSS variable của Elementor luôn).
Trường hợp design sử dụng font custom, upload file font lên transfronter và copy code về cho vào Custom HTML.
Tạo và lưu component để dùng cho nhiều trang
UI Builder | Web component | React Component |
Save as Template | Tạo block code khai báo Component và save template | Tạo block code khai báo Component và save template |
Save as Default |
Gọi component ra sử dụng
Đối với Web component và React component, cái phần lưu Template sẽ chỉ là phần khai báo, còn việc gọi ra sẽ thực hiện ở App Logic (tạo 1 block code), lúc này component đã có sẵn ở biến JS.
Với UI Builder thì khác 1 chút vì phần lưu Template sẽ bao gồm cả render luôn, nên có 2 cách xử lý:
Sau khi gọi template ra, dùng JS để lưu HTML sau đó xóa block template đó đi.
hoặc có thể đặt tag của block Container là
<template />
, mặc định code trong thẻ này sẽ k hiển thị. Lưu ý: Cái này chỉ được áp dụng sau khi có chỉnh sửa vào plugin elements để cho block Container nhận thêm tag. Cùng xem cách sử dụng của<template />
Giờ áp dụng vào lại bài lần trước ta sẽ có hướng xử lý gọn gàng hơn chút như sau:
%[https://www.youtube.com/watch?v=3OwSI92m4t4]
Cái hay của <template /> là nó có thể tự chạy javascript trong thẻ <script />, nên chúng ta không cần phải chạy function rerunHTMLScript nữa.
Quản lý state
UI Builder: dùng function
useState
.state
cần được đồng bộ vớidata attribute
.Web component: dùng
this.setState
.state
cũng cần được đồng bộ vớidata attribute
React: dùng
useState
với React function vàthis.setState
với React class, không cần dùng attribute và có thể dùngprops
thay thế
Quản lý render
UI Builder: đồng bộ giữa
data attribute
ở parent với giao diện, khi data attribute đổi thì giao diện cũng đổi. setinnerHTML
dùngtemplate string
để chèn state, cẩn thận khi sử dụnginnerHTML
vì sẽ xuất hiện nháy. Khi bị nháy thì chuyển sang set attribute bằng JS. Loop qua state để render hàng loạt dùngtemplateEl.content
để tạo node vàappendChild
.Web compoment: cũng set
innerHTML
dùngtemplate string
để chèn state, cũng cẩn thận khi sử dụnginnerHTML
, nếu bị nháy thì chuyển sang dùngmapStateRender
. Loop qua state để render hàng loạt component con thì đơn giản hơn vì chỉ cần chèn thẳng tag của thằng component con vào là đc, không cần dùng<template />
.React: return thẳng mã html mà không sợ bị nháy (JSX). loop của state để render hàng loạt component con bằng việc dùng trực tiếp
.map
từ biến.
Quản lý listener
UI Builder: khai báo listener của phần tử bên trong component ở
render
. thông báo ra bên ngoài bằng cách update attributeevent-*
. bên ngoài listen bằngonAttributeChange
.Web component: cũng khai báo listener của phần tử bên trong ở
render
. Viết thẳng method vào class và gọi thẳng từ element sau khi đã querySelector. VD:const inputElement = document.querySelector('input-component'); inputElement.onEnter = () => {};
React: Viết thẳng trực tiếp trong code JSX. Báo ra ngoài component bằng
props
. VD:<Input onEnter={() => {}} />
.
Style
UI Builder: Dùng trực tiếp UI Builder tạo giao diện, có thể dùng thêm Custom CSS ở tab Advance. Hoặc tạo hẳn 1 block HTML để style thêm bằng code CSS.
Web component: viết
renderCSSContainer
và viếtrenderStyle
để dùng trongrender
. Luôn ghi nhớ các code CSS bên ngoài component sẽ k tác động đến các phần tử bên trong component.React: có thể đặt
className
để nhận style bằng class, hoặc viết thẳng style vào qua object style. VD:<div style={{ backgroundColor: 'white' }} />
. Lưu ý style này sẽ viết theo kiểu style của JS DOM (camel case). VD:const divEL = document.querySelector('div'); divEL.style.backgroundColor = 'white';
.
Cách để các loại giao diện giao tiếp với nhau
Vì bản chất tất cả đều dùng để làm giao diện, nên cuối cùng chúng sẽ đề được render thành các tag HTML. Do đó, cách chung nhất để giao tiếp với nhau là thông qua attribute:
dùng
getAttribute
,setAttribute
để đọc, ghi giá trị. vớidata attribute
thì dùng.dataset
cho tiện.dùng
onAttributeChange
để listen thay đổi.các event xảy ra bên trong component cũng nên thông báo thông qua attribute
event-*
Với React thì để đồng bộ giữa attribute và state thì chúng ta dùng code sau:
const { useEffect, useState, useRef } = React;
const useAttrState = (initialState, arrayOfDataAttr) => {
const [state, setState] = useState({});
const stateRef = useRef(state);
const getState = () => stateRef.current;
const elementRef = useRef(null);
useEffect(() => {
mapDataAttributeToState(
elementRef.current,
getState,
setState,
arrayOfDataAttr
);
}, []);
useEffect(() => {
stateRef.current = state;
}, [state]);
return [state, setState, elementRef];
}
const Task = () => {
const [state, setState, elementRef] = useAttrState({
text: '',
important: '0',
subtask: '0',
type: 'unfinished',
}, ['text', 'important', 'subtask', 'type']);
return (
<div ref={elementRef}>...</div>
)
};
Lưu ý:
Nếu chỉ giao tiếp giữa các React component với nhau thì k cần dùng đến attribute mà dùng props. props nó như kiểu 1 loại Virtual attribute, sẽ không thể hiện ra tag html
attribute phần lớn chỉ nhận dữ liệu là string, trong khi props có thể nhận mọi loại biến JS. có thể nhận cả function (do đó có thể gắn listener trực tiếp vào).
đoạn code trên thì chúng ta có thể khai báo
useAttrState
ở common funcs và dùng đi dùng lại ở nhiều component. Đó được gọi làReact hook
1 concept khá phổ biến của React để tái sử dụng logic.
Subscribe to my newsletter
Read articles from Lê Quang Huy directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Lê Quang Huy
Lê Quang Huy
I am a developer, I write blogs occasionally. I hope you will find something new when reading my blogs.