Hi everyone, this is Kasong.
It is said that Hooks
is the future React
Hooks
the best practice for 061265afc19de4?
Regarding this knowledge, the official document does not mention it at all.
Therefore, in actual projects, problems similar to the following often occur:
// ...
useEffect(() => {
fetchData(a, b).then(
// ...
)
}, [a, b])
//...
useEffect
relies on the a b
. When any one of them changes, it will execute fetchData
request data.
When the application becomes complex, it becomes more and more difficult a
and b
fetchData
time and day interface adjustments, 061265afc19ef9 also needs the status c
as a parameter. Then the difficulty of tracking state changes will be further increased.
Will eventually lead to:
fetchData
meaningless 061265afc19fd1 multiple calls- Heavy logic appears difficult to trace
bug
Some friends will say: You can encapsulate customize Hook.
This just hides the problem deeper...
how to solve this problem
The reason is that the nature of these problems: side effects too many, can be used as side effects things are also too many. This led to the abuse of useEffect
Therefore, in order to solve the problem of abuse, it is necessary to provide official solutions side effects
In this way, there is a specific solution to the specific problem, so that the useEffect
will not be a shuttle.
Seeing the change from a PR
Recently, React
has a very humble PR :
It roughly means:
Before, when component (you are in an already unloaded unmounted
) call setState
will trigger a warning
, this PR
will remove this warning
.
For example, the following code assembly mount
registration when handleChange
:
useEffect(() => {
function handleChange() {
setState(store.getState())
}
store.subscribe(handleChange)
return () => store.unsubscribe(handleChange)
}, [])
If you forget to write this line of unbinding code:
return () => store.unsubscribe(handleChange)
handleChange
may also be called after the component is uninstalled setState
is called.
This is a potential memory leak.
In the previous React
, this behavior will be reported to warning
.
Then why remove warning
under this behavior?
Behind the PR
On the one hand, this warning
has a certain probability of misjudgment. For example, clicks the button to submit the form :
async function handleSubmit() {
setPending(true)
await post('/someapi')
setPending(false)
}
After clicking the button, call setPending
trigger the loading
icon, and then initiate the post
request.
It is possible that the component will be uninstalled before the request is returned. At this time, it will call:
setPending(false)
There is no risk of memory leaks, but warning
will be reported.
However, there is another more essential reason for the removal of warning
In the first example, we useEffect
call store.subscribe
, this behavior can be categorized as:
Subscribe to external sources in the component
What is external source ?
Any change is not controlled by React or not is external source .
for example:
- Various third-party state management libraries
- Hope that the
location.hash
change will trigger a component update
In the future, all such behaviors will converge to useMutableSource
Hook
.
More examples
For another example, for the I/O
operation (such as the request data ) this kind of logic that everyone will put in the useEffect
, the future use of resource
combined with Suspense
may be a better choice:
const resource = fetchDetail();
function Page() {
return (
<Suspense fallback={<h1>Loading...</h1>}>
<Details/>
</Suspense>
);
}
function Details() {
const data = resource.read();
return <h1>{data.name}</h1>;
}
In the above example, calling fetchDetail
will initiate a data request.
Details
component calls resource.read
directly consume the data.
If the data has not been returned, the view will render the nearest Suspense
of fallback
(that is, <h1>Loading...</h1>
).
Summarize
side effects of are many and varied. There was no choice before, and only useEffect
could be used.
With React18
stable, face different side effects scene, there will be a clearer solution.
At that time, it may finally usher in the era Hooks
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。