Làm tính năng Theme trong React?
Bài viết được sự cho phép của tác giả Lưu Bình An
Để hỗ trợ tính năng Theme, cho phép người dùng lựa chọn kiểu giao diện mà họ thích, trong React, bạn sẽ có thể tiếp cận 1 trong 2 cách dùng CSS-in-JS hoặc dùng CSS variable (tất nhiên không có hỗ trợ với IE)
Nếu dùng CSS-in-JS bạn sẽ có thể làm được nhiều thứ hơn, bạn có một bộ công cụ đủ các đạo cụ để mua mai trong JS. Bài viết này sẽ chỉ ra tại sao bạn nên dùng CSS variable cho nhu cầu làm theme
Tuyển dụng it react không yêu cầu kinh nghiệm
Nếu dùng CSS-in-JS, trong React bạn sẽ tổ chức một ThemeProvider
bằng React Context, dùng hook useTheme
để lấy giá trị trong ThemeProvider
, sẽ như thế này
import * as React from 'react'
import styled from '@emotion/styled'
import {ThemeProvider} from 'emotion-theming'
const themes = {
light: {
colors: {
primary: 'deeppink',
background: 'white',
},
},
dark: {
colors: {
primary: 'lightpink',
background: 'black',
},
},
}
const PrimaryText = styled.div(({theme}) => ({
padding: 20,
color: theme.colors.primary,
backgroundColor: theme.colors.background,
}))
function ThemeToggler({theme, onClick}) {
const nextTheme = theme === 'light' ? 'dark' : 'light'
return (
<button onClick={() => onClick(nextTheme)}>
Change to {nextTheme} mode
</button>
)
}
function App() {
const [theme, setTheme] = React.useState('light')
return (
<ThemeProvider theme={themes[theme]}>
<PrimaryText>This text is the primary color</PrimaryText>
<ThemeToggler
theme={theme}
onClick={(nextTheme) => setTheme(nextTheme)}
/>
</ThemeProvider>
)
}
export default App
Nếu dùng CSS variable, chúng ta khai bao một bộ các biến cần dùng, rồi chèn thêm data-theme
cho thẻ body
CSS
body[data-theme='light'] {
--colors-primary: deeppink;
--colors-background: white;
}
body[data-theme='dark'] {
--colors-primary: lightpink;
--colors-background: black;
}
Phần implement của React component lúc này sửa lại
import * as React from 'react'
import './css-vars.css'
import styled from '@emotion/styled'
const PrimaryText = styled.div({
padding: 20,
color: 'var(--colors-primary)',
backgroundColor: 'var(--colors-background)',
})
function ThemeToggler() {
const [theme, setTheme] = React.useState('light')
const nextTheme = theme === 'light' ? 'dark' : 'light'
React.useEffect(() => {
document.body.dataset.theme = theme
}, [theme])
return (
<button onClick={() => setTheme(nextTheme)}>
Change to {nextTheme} mode
</button>
)
}
function App() {
return (
<div>
<PrimaryText>This text is the primary color</PrimaryText>
<ThemeToggler />
</div>
)
}
export default App
Thẳng thắn mà nói, cả 2 cách làm này đều cho kết quả như nhau về mặt trãi nghiệm sử dụng, dùng CSS-in-JS sẽ có chút cảm giác hơi quá đà kỹ thuật, từ chuyên ngành là over-engineering.
Về hiệu năng thì sao?
ThemeProvider
CSS variable
Cũng không nhất thiết phải nhìn vào con số mili giây phải tốn cho việc render, vì simple này khá là bé. Bạn cứ hình dùng nếu một cây React Component với hàng trăm component con lồng ghép nhau, khi thay đổi giá trị trong ThemeProvider, tất cả những component đều bị render lại thì sẽ như thế nào? Việc dùng CSS variable sẽ mang lại hiệu quả hơn nhiều vì trình duyệt không phải làm quá nhiều thứ như cách 1.
Có một lý do mà mình cho là hơi ngụy biện khi khăng khăng đòi dùng JS-in-CSS theo mình đoán là các bạn thật sự chưa đủ tự tin cũng như “trình” để viết CSS hiện đại, bạn chuyên tâm nâng tầm JS của mình mà quên mất việc nâng tầm CSS, vón đã phát triển rất xa từ cái thời bạn dùng float
Use CSS Variables instead of React Context
Bài viết gốc được đăng tải tại vuilaptrinh.com
Có thể bạn quan tâm:
- React Context API và các Higher-order Components
- React hook là gì và lợi ích mà React hook đem lại
- Bỏ túi Cheatsheet React cho năm 2020 (kèm ví dụ thực tế)
Xem thêm tuyển dụng nhân viên it hấp dẫn trên TopDev
- B BenQ RD Series – Dòng Màn Hình Lập Trình 4k+ Đầu Tiên Trên Thế Giới
- i iOS 18 có gì mới? Có nên cập nhật iOS 18 cho iPhone của bạn?
- G Gamma AI là gì? Cách tạo slide chuyên nghiệp chỉ trong vài phút
- P Power BI là gì? Vì sao doanh nghiệp nên sử dụng PBI?
- K KICC HCMC x TOPDEV – Bước đệm nâng tầm sự nghiệp cho nhân tài IT Việt Nam
- T Trello là gì? Cách sử dụng Trello để quản lý công việc
- T TOP 10 SỰ KIỆN CÔNG NGHỆ THƯỜNG NIÊN KHÔNG NÊN BỎ LỠ
- T Tìm hiểu Laptop AI – So sánh Laptop AI với Laptop thường
- M MySQL vs MS SQL Server: Phân biệt hai RDBMS phổ biến nhất
- S SearchGPT là gì? Công cụ tìm kiếm mới có thể đánh bại Google?