Svelte?和?React的比較詳解(一)
比較 Svelte 和 React
在這篇文章中,我將告訴您我更喜歡 Svelte 還是 React,不能以個人意見代表誰好誰壞。以及我發(fā)現(xiàn)使用這兩個框架的一些區(qū)別。
驗證
在 React 中創(chuàng)建了一個 useCurrentUser 的鉤子,用于偵聽身份驗證更改并相應(yīng)地設(shè)置一些狀態(tài)。然后我可以在 React 任何地方使用,并在身份驗證更改時重新渲染頁面。
export const useCurrentUser = () => {
const [currentUser, setCurrentUser] = useState(undefined)
useEffect(() => {
return firebase.auth().onAuthStateChanged((details) => {
setCurrentUser(
details
? {
displayName: details.displayName,
provider: {
'github.com': 'GitHub',
}[details.providerData[0].providerId],
uid: details.uid,
}
: null
)
})
}, [])
return [currentUser]
}在任何組件中,都可以使用:
const [currentUser] = useCurrentUser()
這可以讓任何組件快速獲取當(dāng)前用戶。唯一的缺點是在每一個頁面都有一個 onAuthStateChanged 監(jiān)聽器,
但可以通過僅綁定一個偵聽器或?qū)?dāng)前用戶置于執(zhí)行上下文中來解決。
執(zhí)行上下文,在 Svelte 中可以采用的方法并使用可寫存儲。
export const currentUser = writable()
export const listenForAuthChanges = () => {
return firebase.auth().onAuthStateChanged((details) => {
if (details) {
currentUser.set({
displayName: details.displayName,
provider: {
'github.com': 'GitHub',
}[details.providerData[0].providerId],
uid: details.uid,
})
} else {
currentUser.set(null)
}
})
}在頂級 Svelte 組件中,我可以在 onMount 中調(diào)用它,它將在掛載組件時執(zhí)行(該函數(shù)是 return 編輯的,因此我們在刪除組件時取消訂閱,就像 useEffect 讓你返回一個函數(shù)銷毀)。
onMount(() => {
return listenForAuthChanges()
})這樣在 Svelte 代碼庫中的任何地方,組件都可以導(dǎo)入 currentUser 可寫存儲。您可以訂閱它并手動控制狀態(tài)更改:
currentUser.subscribe(newValue => {
...
})或者,如果你想讀取最新的值:
console.log($currentUser)
這就是 Svelte 的語法技巧厲害的地方;這個$前綴會獲取最新的值。
雖然對于初學(xué)者來說有點奇怪。但是,Svelte 就省去調(diào)用 subscribe 的API。
就基本身份驗證而言,兩個庫似乎都采用了類似的方法。雖然確切語法略有不同,但兩者都允許您訂閱 Firebase 偵聽器并在身份驗證狀態(tài)更改時獲得更新。
從使用者角度開發(fā)
Pomodone 是一個 25 分鐘的計時器,并盡可能準確。如果瀏覽器選項卡處于后臺(不是焦點選項卡),大多數(shù)瀏覽器將降低其 setTimeout 調(diào)用的優(yōu)先級并且不會嚴格按時運行它們。大多數(shù)時候在網(wǎng)絡(luò)上這不是什么大不了的事,但是當(dāng)用戶通過您的應(yīng)用程序跟蹤 25 分鐘的工作時,它就有問題,在 25 分鐘的過程中,任何輕微的時間漂移都會導(dǎo)致最終時間相差甚遠。但是,如果將這些超時轉(zhuǎn)移到 Web Worker 中,它們應(yīng)該會按時運行,并且不會被瀏覽器取消優(yōu)先級。
因此,在我的 Tracker 組件中,我需要實例化一個 Web Worker,向它發(fā)送消息并接收數(shù)據(jù)(例如剩余時間)。這時我發(fā)現(xiàn) React 比 Svelte 更重管理的一個領(lǐng)域;
因為 React 組件在每次重新渲染時都會重新執(zhí)行,所以很容易導(dǎo)致創(chuàng)建數(shù)千個 worker!必須使用 useRef 通過維護對您創(chuàng)建的工作程序的引用來避免此問題。
首先,我設(shè)置了組件所需的初始狀態(tài):
const [currentPom, setCurrentPom] = useState(null) const [currentUser] = useCurrentUser() const worker = useRef(null)
然后創(chuàng)建一個 useEffect 掛鉤,如果需要,它將實例化 worker,并綁定一個事件監(jiān)聽器來監(jiān)聽消息:
useEffect(() => {
if (!worker.current) {
worker.current = new Worker(workerURL)
window.worker = worker.current
}
const onMessage = (event) => {
if (event.data.name === 'tick') {
setCurrentPom((currentPom) => ({
...currentPom,
secondsRemaining: event.data.counter,
}))
} else if (event.data.name === 'start') {
// More branches removed here to save space...
}
}
worker.current.addEventListener('message', onMessage)
return () => {
worker.current.removeEventListener('message', onMessage)
}
}, [currentUser])然后,當(dāng)用戶點擊“開始”按鈕時,我必須向 worker 發(fā)送一條消息:
const onStartPom = () => {
if (!worker.current) return
worker.current.postMessage('startTimer')
}Svelte 看起來非常相似,但在我看來有兩個小的變化使 Svelte 代碼更易于閱讀:
- 我們不必將 worker 保留在
useRef中,只需將其分配給一個變量即可。 - 我們可以更輕松地將事件偵聽器代碼拉出到一個函數(shù)中,因為該函數(shù)不會成為
useEffect的依賴項——此時我們必須將它包裝在useCallback中。
let worker
onMount(() => {
worker = new Worker(workerURL)
worker.addEventListener('message', onWorkerMessage)
return () => {
worker.removeEventListener('message', onWorkerMessage)
}
})我們也不必使用 React 的 setX(oldX => newX) 約定來設(shè)置狀態(tài),只需改變局部變量即可:
function onWorkerMessage(event) {
if (event.data.name === 'tick') {
currentPom = {
...currentPom,
secondsRemaining: event.data.counter,
}
} else if (event.data.name === 'start') {
// More branches here removed to save space...
}
}這就是 Svelte 好的地方;兩者非常相似,但是一旦習(xí)慣 Svelte, 感覺React就像在跳圈。你不能創(chuàng)建一個工作實例,它必須進入 useRef ,然后你不能輕易地將代碼拉出到一個函數(shù)中而不需要 useCallback 所以它可以是對 useEffect 的安全依賴。
使用 Svelte,我編寫的代碼更接近于“純”JavaScript,而在 React 中,我的更多代碼被包裝在 React 原語中。
條件渲染
React 它只是 JavaScript。與 Svelte 的模板語言相比, React 中你不使用獨特的模板語法而是在編寫 JavaScript:
SideTabs
<ul>
{pomsForCurrentDay.map(entryData, index) => {
const finishedAt = format(new Date(entryData.timeFinished), 'H:mm:ss')
return <li title={`Finished at ${finishedAt}`}>{index + 1}</li>
})}
</ul>在過去,我發(fā)現(xiàn)模板語言是趨勢但不靈活,但 Svelte 提供了恰到好處的模板,同時也使您能夠使用 JavaScript。也就是說,我總是會發(fā)現(xiàn) React 的方法更簡單 - 至少在我的腦海中 - 我認為對于熟悉 JavaScript 并正在學(xué)習(xí)庫的人來說更友好。
然而,在渲染組件時,Svelte 確實對其語法進行了一些不錯的修改(感覺非常像 JSX)。我最喜歡的是折疊道具的能力:
<History pomodoros={pomodoros} />Svelte (collapsed props)
<History {pomodoros}/>到此這篇關(guān)于Svelte 和 React的比較詳解(一)的文章就介紹到這了,更多相關(guān)Svelte 和 React比較內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決JSON.parse轉(zhuǎn)化不規(guī)范json字符串的問題
這篇文章主要介紹了解決JSON.parse轉(zhuǎn)化不規(guī)范json字符串的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09
JavaScript將數(shù)組轉(zhuǎn)換為鏈表的方法
這篇文章主要介紹了JavaScript將數(shù)組轉(zhuǎn)換為鏈表的方法,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2020-02-02
request請求獲取參數(shù)的實現(xiàn)方法(post和get兩種方式)
下面小編就為大家?guī)硪黄猺equest請求獲取參數(shù)的實現(xiàn)方法(post和get兩種方式)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-09-09
在table中插入多行的js代碼(與insertAdjacentHTML相似的功能)
在table中插入多行,能使用與insertAdjacentHTML相似的功能2010-06-06
setTimeout函數(shù)兼容各主流瀏覽器運行執(zhí)行效果實例
setTimeout是一個很不錯的函數(shù),網(wǎng)站頁面前端工程師經(jīng)常將其用于幾秒后執(zhí)行的動作,下文要講的setTimeout可以很好地兼容IE6,7,8,9以及谷歌等主流瀏覽器2013-06-06
分享10個優(yōu)化代碼的CSS和JavaScript工具
如果你想在保持文件的時候或執(zhí) 行的階段lint代碼,那么linting工具也可以如你所愿。這取決于個人的選擇。如果你正在找尋用于CSS和JavaScript最好的 linting工具,那么請繼續(xù)閱讀2016-05-05

