Hello, everyone. I'm Carson.
the following React
component code uses three use
keywords. Do you understand their role?
'use client'
function App() {
using data = use(ctx);
// ...
}
it is true that I haven't written React
for several days, and I can't even understand the grammar. This article will talk about the respective meanings of these use
keywords.
use client
begins with the 'use client'
declaration at the top of the code, which is used in a manner similar to the strict mode declaration:
'use strict';
// here is the JavaScript code in strict mode
The 'use client'
declaration is defined in the RSC
( React Server Component
, server-side component) protocol.
the React
application of RSC
is enabled. All components are rendered on the server by default (you can experience it through Next v13
). Only component files that declare 'use client'
are rendered at the front end.
suppose our React
application component structure is as follows, where red represents server component , blue represents client component (declare 'use client'
):
then when the application is packaged, the D and E components will be packaged into separate files. On the front end, React
can render A, B, C components directly. But for D and E, you need to request back the component code in the form of JSONP
before rendering.
using keyword
then comes the using
keyword before the data
variable:
using data = use(ctx);
The using
keyword is proposed by tc39
proposal ECMAScript Explicit Resource Management , and is used to provide unified lifecycle management (when to allocate, when to release, etc.) for various resources (memory, Icando O
, etc.).
at the same time, TS v5.2
first introduced this keyword. So, in the next explanation, we take the using
keyword in TS
as the standard.
The effect of using
is somewhat similar to the destroy
function of useEffect
. When we bind an event to the create
function of useEffect
, we can unbind it in the destroy
function:
function App() {
useEffect(() => {
console.log("here is the create function")
return () => {
console.log("here is the destroy function")
}
}, [])
}
Similarly, when we declare an object that contains a [Symbol.dispose]
method through the using
keyword, the declared [Symbol.dispose]
method executes when leaving the current scope:
{
const getResource = () => {
return {
[Symbol.dispose]: () => {
console.log('Let 's go!')
}
}
}
using resource = getResource();
}
// when the code is executed, it will print out!
mainly performs some resource release operations within the [Symbol.dispose]
method.
for example, when we operate a database, if we want to consider disconnecting the database after operation , we might write the following code:
const db = await connectDB();
try {
// perform database operations
} finally {
// disconnect the database
await db.close();
}
if you use the using
keyword, the code is as follows:
const connect = async () => {
const db = await connectDB();
return {
db,
[Symbol.asyncDispose]: () => db.close()
};
};
// use
{
using { db } = await connect();
// perform database operations
}
// disconnect automatically when leaving the scope
in conjunction with async await
, you can reduce the possibility of leaking memory due to forgetting to release resources .
use method
Last is the new native hook
released after React v18.3
-- use
:
using data = use(ctx);
this hook
can receive two types of data:
React Context
now use
has the same effect as useContext
.
promise
at this point, if the promise
is in the pending
state, the nearest ancestor & lt;Suspense/>
component can render fallback
.
for example, in the following code, if the & lt;Cpn / & gt;
component or its descendant component uses use
and promise
is in the pending
state (such as requesting backend resources):
function App() {
return (
<div>
<Suspense fallback={<div>loading...</div>}>
<Cpn />
</Suspense>
</div>
);
}
then, the page renders the following result:
<div>
<div>loading...</div>
</div>
when the request is successful, & lt;Cpn / & gt;
is rendered.
Summary
for the code mentioned at the beginning:
'use client'
function App() {
using data = use(ctx);
// ...
}
means:
-
this is a client component
-
if the variable
ctx
passed touse
isReact Context
, thenuse
has the same effect asuseContext
-
if the variable
ctx
passed touse
ispromise
, usewith the most recent
& lt;Suspense/>
-
if the return value of
use
contains[Symbol.dispose]
, thenApp
componentrender
executes[Symbol.dispose]
methodafter completion.
one file, three use
related grammars, are you confused?