3
头图

Hello everyone, I'm Casson.

Have you or your colleagues used useEffect in the following scenarios:

When you want to make a request after 状态a changes, you use useEffect :

 useEffect(() => {
  fetch(xxx);
}, [a])

This code works as expected, and it works fine after going live.

As the requirements continue to iterate, other places will also be modified 状态a . But in that requirement, there is no need to make the request after the 状态a change.

You don't want to touch the previous code, you have to fix this bug , so you add the judgment condition:

 useEffect(() => {
  if (xxxx) {
    fetch(xxx);
  }
}, [a])

One day, the needs changed again! The request now also requires b field.

This is very simple, you can easily add b as a dependency of useEffect :

 useEffect(() => {
  if (xxxx) {
    fetch(xxx);
  }
}, [a, b])

Over time, you gradually discover:

  • Whether to send the request is related to the if condition
  • Whether sending a request is also related to dependencies such as a, b, etc.
  • A, b and other dependencies are related to many requirements

I can't tell when the request will be sent, it's a big head...

If the above scenario seems familiar, then React the solution has been clearly provided in the new document.

Welcome to join the human high-quality front-end framework group , with flying

some theoretical knowledge

This section of the new document is called Synchronizing with Effects and is currently in a draft state.

But some concepts mentioned in it, all React developers should be clear.

First, effect this section belongs to the chapter Escape Hatches .

It can be seen from the naming that developers do not necessarily need to use effect , this is just an escape hatch in special cases.

React There are two important concepts:

  • Rendering code (rendering code)
  • Event handlers (event handler)

Rendering code refers to the component rendering logic written by the developer , which will eventually return a segment JSX .

For example, inside the following component is Rendering code :

 function App() {
  const [name, update] = useState('KaSong');
  
  return <div>Hello {name}</div>;
}

Rendering code is characterized by: it should be a pure function without side effects .

The following Rendering code includes side effects ( count change), which is not recommended:

 let count = 0;

function App() {
  count++;
  const [name, update] = useState('KaSong');
  
  return <div>Hello {name}</div>;
}

dealing with side effects

Event handlers is a function included inside the component to perform user operations, which can include 副作用 .

The following operations belong to Event handlers :

  • Update input input box
  • submit Form
  • Navigate to other pages

In the following example, the changeName method inside the component belongs to Event handlers :

 function App() {
  const [name, update] = useState('KaSong');
  
  const changeName = () => {
    update('KaKaSong');
  }
  
  return <div onClick={changeName}>Hello {name}</div>;
}

However, not all side effects can be resolved in Event handlers .

For example, in a chat room, sending a message is triggered by the user and should be handed over to Event handlers for processing.

In addition, the chat room needs to maintain a long connection with the server at any time. The behavior of maintaining a long connection is a side effect, but it is not triggered by user behavior.

For this: the side effects triggered after view rendering belong to effect and should be handed over to useEffect for processing.

Back to the starting example:

When you want to initiate a request after 状态a changes, you should first make clear that your requirements are:

The state a changes, and then a request needs to be initiated

still

A user behavior needs to initiate a request, and the request depends on the state a as a parameter ?

If it is the latter, which is a side effect triggered by user behavior, then the relevant logic should be placed in Event handlers .

Suppose the previous code logic is:

  1. Click the button to trigger 状态a change
  2. useEffect Execute, send request

should be modified to:

  1. Click the button to get the value of 状态a in the event callback
  2. Send request in event callback

After this modification, there is no longer a causal relationship between the change of state a and the sending of the request . Subsequent modifications to 状态a will no longer have concerns about unintentionally triggering the request .

Summarize

When we write components, we should try to write the components as pure functions.

For side effects in components, first of all, it should be clear:

Is it triggered by user behavior or actively triggered after the view is rendered ?

For the former, put the logic in Event handlers for processing.

For the latter, use useEffect for processing.

That's why useEffect is in a new document called Escape Hatches -- in most cases, you won't use useEffect , it's just not otherwise. Escape pods when acclimated.


卡颂
3.1k 声望16.7k 粉丝