首頁 > web前端 > js教程 > 主體

React 中的 useEffect 其實是一個 Effect 嗎?

王林
發布: 2024-09-12 10:31:00
原創
419 人瀏覽過

反應:我選擇你

我開始了我自己的 React JS 之旅,作為我的入門 Pokemon 來探索 Javascript 框架世界。乍一看,我愛上了它,因為它減少了大量命令式 DOM 操作程式碼。我真的很喜歡框架根據狀態自動操作 DOM 的想法。

Is useEffect in React is actually an Effect?

一開始,我沒有考慮 React 的大小和它消耗的內存,這可以在重量上擊敗 Snorlax
學習 React 後,我接觸到了很多框架,像是 Vue、Angular、Svelte。當我終於接觸到 SolidJS 時,我的眼睛睜開了

Is useEffect in React is actually an Effect?

我開始關注 SolidJS 的作者 Ryan Carniato 的直播和文章。他完全改變了我看待框架的方式。我開始了解 Javascript 框架的反應系統。當我回頭看到 My Starter Pokemon React 及其反應性和渲染系統時,我無法控制自己的笑

Is useEffect in React is actually an Effect?

好像我從一開始就被愚弄了。為什麼每當狀態改變時都需要重新運行一切?如果是這樣那麼為什麼我們真的需要一個名為 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中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!