I can't read grammar without writing React for a few days.

June 30, 2023 1218hotness 0likes 0comments

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 to use is React Context , then use has the same effect as useContext

  • if the variable ctx passed to use is promise , use

    with the most recent & lt;Suspense/>

  • if the return value of use contains [Symbol.dispose] , then App component render executes [Symbol.dispose] method

    after completion.

one file, three use related grammars, are you confused?

InterServer Web Hosting and VPS

Aaron

Hello, my name is Aaron and I am a freelance front-end developer

Comments