React 中的 useEffect 其實是一個 Effect 嗎?
反應:我選擇你
我開始了我自己的 React JS 之旅,作為我的入門 Pokemon 來探索 Javascript 框架世界。乍一看,我愛上了它,因為它減少了大量命令式 DOM 操作程式碼。我真的很喜歡框架根據狀態自動操作 DOM 的想法。
一開始,我沒有考慮 React 的大小和它消耗的內存,這可以在重量上擊敗 Snorlax。
學習 React 後,我接觸到了很多框架,像是 Vue、Angular、Svelte。當我終於接觸到 SolidJS 時,我的眼睛睜開了
我開始關注 SolidJS 的作者 Ryan Carniato 的直播和文章。他完全改變了我看待框架的方式。我開始了解 Javascript 框架的反應系統。當我回頭看到 My Starter Pokemon React 及其反應性和渲染系統時,我無法控制自己的笑
好像我從一開始就被愚弄了。為什麼每當狀態改變時都需要重新運行一切?如果是這樣那麼為什麼我們真的需要一個名為 useEffect 的鉤子來充當副作用。
現在進入文章標題
我將這篇文章命名為 React 中的 useEffect 實際上是一個 Effect 嗎?就像Vegapunk 睜開了人們關於政府的眼睛(抱歉劇透了 OP 粉絲) 一樣,讓你對 React 睜開眼睛。對此有很多值得批評的想法。所以今天是使用Effect的日子,他隱藏了自己的真名,說謊最多。
如果你是初學者或你問一些 React 初學者,他們會對 useEffect 的解釋為
只要依賴陣列中的值發生變化就會重新運行的函數。
如果你是那個人,你真的很幸運知道你被教導是錯誤的真相。每當發生變化時,React 就會重新運行,所以不需要重新運行函數,因為不需要它。下面我就來解釋一下真相
效果的真正意義是什麼?
讓我解釋一下效果的真正意義。在Reactivity系統中,Effect實際上被稱為Side Effect。讓我們從一個例子開始
const name = "John Doe" createEffect(()=>{ console.log("New name", name) },[name])
此處 createEffect 函數接受一個函數,只要第二個參數中的 Array 中的值發生變化,函數就會重新運行。 createEffect 中的函數是名稱的副作用,換句話說,函數取決於狀態名稱。每當名稱的值發生變更時,副作用就會重新運行。這就是副作用真正的意思。
React 實際上做了什麼?
讓我用 React 寫相同的程式碼
const [name, setName] = useState("John Doe") useEffect(()=>{ console.log("New name", name) },[name]) setName("Jane Doe")
每當呼叫 setName 時,useEffect 就會重新運作。我完全明白了。讓我透過簡單地刪除 useEffect 來給出等效程式碼。它也有效,因為 React 的 useState 不會建立任何反應狀態
const [name, setName] = useState("John Doe") console.log("New name", name) setName("Jane Doe")
TADA! 它在 React 中運作得很好,因為每當 useState 的狀態時它都會重新運行
變化。我再舉個例子來解釋useEffect。
const [name, setName] = useState("John Doe") const [age, setAge] = useState(18) console.log("New name", name) setAge(21)
現在每當年齡改變時,console.log("New name", name)也會被執行,這不是我們想要的。所以我們用 useEffect 來包裝它。
const [name, setName] = useState("John Doe") const [age, setAge] = useState(18) useEffect(()=>{ console.log("New name", name) },[name]) setName("Jane Doe")
現已修復。因此,useEffect 實際上是阻止執行,這與 Effects 完全相反。我希望你明白它的真正作用。這裡有 useEffect 的正確解釋。
useEffect 是一個鉤子,僅當狀態發生變化時才執行
我知道副作用的解釋是類似的,但它就像硬幣的反面。
副作用解釋
副作用是每當狀態改變時執行的函數
在反應系統中,除了Effects重新運行之外沒有什麼,Effects是只在狀態改變時運行的函數。
在React中,除了Effects重新運行之外的所有內容,Effects都是在依賴數組沒有變化的情況下阻止執行的函數
最後我希望您了解 useEffect 的真正用途。上面的例子被稱為「你可能不需要效果的最差實踐」。我完全明白了。但這就像他們建議我們不要使用 useEffect 作為 Effect。
大謊言
解釋為
useEffect 是一個 React Hook,可讓您將元件與外部系統同步。
I can't totally get it because The Phrase synchronize with external system means
The system's internal state is updated to match the state of the external system.
But in reality, useEffect had nothing to do with that. useSyncExternalStore does works in problem with some quirks ( Really this problem can't be solved 100%. For now , save that for My Another article ).
Just think about this facts that React reruns code whenever state changes and useEffect is commonly used along with React state, Then Why do we need to run something based on a state? because always reruns whenever something changes.
I found a page named as Synchronizing with Effects at React Official Docs which explains about it . At there, They explained that as
Effects let you run some code after rendering so that you can synchronize your component with some system outside of React.
From above lines, It is clear that useEffect lets you write a function which executes after rendering of React. Then WTF it is named as useEffect? Does this had any kind of connection with Effect as it's name implies? It's more similar to window.onload of DOM API.
I still can't digest the example they gave
import { useState, useRef, useEffect } from 'react'; function VideoPlayer({ src, isPlaying }) { const ref = useRef(null); if (isPlaying) { ref.current.play(); // Calling these while rendering isn't allowed. } else { ref.current.pause(); // Also, this crashes. } return <video ref={ref} src={src} loop playsInline />; } export default function App() { const [isPlaying, setIsPlaying] = useState(false); return ( <> <button onClick={() => setIsPlaying(!isPlaying)}> {isPlaying ? 'Pause' : 'Play'} </button> <VideoPlayer isPlaying={isPlaying} src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4" /> </> ); }
Here is the reason the error If You try to run it
Runtime Error App.js: Cannot read properties of null (reading 'pause') (9:16) 6 | if (isPlaying) { 7 | ref.current.play(); // Calling these while rendering isn't allowed. 8 | } else { > 9 | ref.current.pause(); // Also, this crashes. ^ 10 | } 11 | 12 | return <video ref={ref} src={src} loop playsInline />;
They told to us wrap it inside useEffect to solve this by
useEffect(() => { if (isPlaying) { ref.current.play(); } else { ref.current.pause(); } });
because ref.current is set to null before rendering. But I could solve this by simply changed it to
if (isPlaying) { ref.current?.play(); } else { ref.current?.pause(); }
If It's that what they willing to do, They it should be named as onMount like Vuejs not useEffect because effects at other library like VueJS, SolidJS really does side effect.
Here is the explanation They connected the above example with synchronisation
In this example, The “external system” you synchronized to React state was the browser media API
Does that really make any sense? I still don't know Why used synchronized here?. Here Browser Media API is available after First Render So Then Why there is a necessary of Effect here? It's a Sick Example for Effect. I never thought They would explain Effect with Example Code.
Another Joke
Effects let you specify side effects that are caused by rendering itself, rather than by a particular event.
It found this under the title What are Effects and how are they different from events? and gave above example code for this. After understanding What React really does in name of Effect and reading My Explanation, Could you connect anything?. They gave explanation of Effect of Reactivity System But They did exactly opposite. This is what I always wanted to express to Others
Final Thoughts
I hope You understand What does Effect means? and What React does in name of Effect?. After thinking All this shits, I finally decided to call useEffect
as usePreventExecution. I knew that name given by me is sick ;-) . But It is nothing when compares to What They stated about it at Official Documentation. If You found any other suitable name, Let me know at Comments.
以上是React 中的 useEffect 其實是一個 Effect 嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

Python和JavaScript在開發環境上的選擇都很重要。 1)Python的開發環境包括PyCharm、JupyterNotebook和Anaconda,適合數據科學和快速原型開發。 2)JavaScript的開發環境包括Node.js、VSCode和Webpack,適用於前端和後端開發。根據項目需求選擇合適的工具可以提高開發效率和項目成功率。

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。1)C 用于解析JavaScript源码并生成抽象语法树。2)C 负责生成和执行字节码。3)C 实现JIT编译器,在运行时优化和编译热点代码,显著提高JavaScript的执行效率。

JavaScript在網站、移動應用、桌面應用和服務器端編程中均有廣泛應用。 1)在網站開發中,JavaScript與HTML、CSS一起操作DOM,實現動態效果,並支持如jQuery、React等框架。 2)通過ReactNative和Ionic,JavaScript用於開發跨平台移動應用。 3)Electron框架使JavaScript能構建桌面應用。 4)Node.js讓JavaScript在服務器端運行,支持高並發請求。

Python更適合數據科學和自動化,JavaScript更適合前端和全棧開發。 1.Python在數據科學和機器學習中表現出色,使用NumPy、Pandas等庫進行數據處理和建模。 2.Python在自動化和腳本編寫方面簡潔高效。 3.JavaScript在前端開發中不可或缺,用於構建動態網頁和單頁面應用。 4.JavaScript通過Node.js在後端開發中發揮作用,支持全棧開發。
