parent
3edd5f7cc1
commit
772281a8de
6 changed files with 178 additions and 102 deletions
@ -1,30 +1,32 @@ |
|||||||
In React functional components, lifecycle-like behaviors are achieved using hooks: |
In React functional components, lifecycle-like behaviors are achieved using hooks: |
||||||
|
|
||||||
1. **Mounting and Cleanup:** |
## Mounting and Unmounting |
||||||
Utilizing the useEffect hook with an empty dependency array ([]) ensures the hook runs after the component mounts to the DOM. |
|
||||||
|
Utilizing the useEffect hook with an empty dependency array ([]) ensures the hook runs after the component mounts to the DOM. |
||||||
```js |
|
||||||
useEffect(() => { |
```js |
||||||
// do something after component mounts |
useEffect(() => { |
||||||
return () => { |
// do something after component mounts |
||||||
// do something before component unmounts |
return () => { |
||||||
}; |
// do something before component unmounts |
||||||
}, []); |
}; |
||||||
``` |
}, []); |
||||||
|
``` |
||||||
The cleanup function returned within the useEffect callback offers a mechanism for handling tasks when the component is about to **unmount**. |
|
||||||
|
The cleanup function returned within the useEffect callback offers a mechanism for handling tasks when the component is about to **unmount**. |
||||||
2. **Updating:** |
|
||||||
The useEffect hook, when invoked without a dependency array or with specific dependencies, executes after every render or when specified prop/state changes are detected. |
## Updates |
||||||
|
|
||||||
```js |
The useEffect hook, when invoked without a dependency array or with specific dependencies, executes after every render or when specified prop/state changes are detected. |
||||||
useEffect(() => { |
|
||||||
// do something after every render |
```js |
||||||
}); |
useEffect(() => { |
||||||
``` |
// do something after every render |
||||||
|
}); |
||||||
```js |
``` |
||||||
useEffect(() => { |
|
||||||
// do something after specific prop/state changes |
```js |
||||||
}, [state1, state2]); |
useEffect(() => { |
||||||
``` |
// do something after specific prop/state changes |
||||||
|
}, [state1, state2]); |
||||||
|
``` |
||||||
|
@ -1,11 +0,0 @@ |
|||||||
Inline conditionals in React are expressions that can be used to conditionally render elements. They are useful when you want to render different elements based on a condition. They can be used in JSX by wrapping them in curly braces. Some examples of inline conditionals include the `ternary operator`, logical `&&` operator, and the logical `||` operator. |
|
||||||
|
|
||||||
```js |
|
||||||
<div>{condition ? <span>True</span> : <span>False</span>}</div> |
|
||||||
``` |
|
||||||
|
|
||||||
```js |
|
||||||
<div>{condition && <span>True</span>}</div> |
|
||||||
``` |
|
||||||
|
|
||||||
> Note that you can also use the `if` statement, but it cannot be used inside JSX. It can only be used inside a function body. |
|
@ -1,7 +1,39 @@ |
|||||||
You can use React's `React.lazy()` function in conjunction with dynamic `import()` to lazily load a component. This is often combined with `Suspense` to display fallback content while the component is being loaded. |
You can use React's `lazy()` function in conjunction with dynamic `import()` to lazily load a component. This is often combined with `Suspense` to display fallback content while the component is being loaded. |
||||||
|
|
||||||
```js |
```js |
||||||
const MyComponent = React.lazy(() => import('./MyComponent')); |
// The component has to be exported as a default export |
||||||
|
export default function RoadmapRender() { |
||||||
|
return <h1>This is a lazily-loaded component!</h1>; |
||||||
|
} |
||||||
``` |
``` |
||||||
|
|
||||||
> Using this pattern requires that the component being lazy loaded is exported as a default export. |
```js |
||||||
|
import { lazy, Suspense } from 'react'; |
||||||
|
|
||||||
|
const LazyRoadmapRender = lazy(() => delay(import('./RoadmapRender'))); |
||||||
|
|
||||||
|
export function App() { |
||||||
|
const [showRoadmapRender, setShowRoadmapRender] = useState(false); |
||||||
|
return ( |
||||||
|
<> |
||||||
|
<button onClick={() => setShowRoadmapRender(true)}> |
||||||
|
Show RoadmapRender |
||||||
|
</button> |
||||||
|
{showRoadmapRender && ( |
||||||
|
<Suspense fallback={<div>Loading...</div>}> |
||||||
|
<LazyRoadmapRender /> |
||||||
|
</Suspense> |
||||||
|
)} |
||||||
|
</> |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
// Helper function to simulate a 2 seconds delay |
||||||
|
function delay(promise) { |
||||||
|
return new Promise((resolve) => setTimeout(resolve, 2000)).then( |
||||||
|
() => promise |
||||||
|
); |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
The `RoadmapRender` component is lazily loaded and rendered inside the `Suspense` component. While the component is being loaded, the `Suspense` component will display the fallback content. |
||||||
|
@ -0,0 +1,23 @@ |
|||||||
|
Suspense is a component in React that lets you specify the fallback content to display while waiting for a component to load. It is used in conjunction with `lazy()` to lazily load components. |
||||||
|
|
||||||
|
```js |
||||||
|
import { lazy, Suspense } from 'react'; |
||||||
|
|
||||||
|
const LazyRoadmapRender = lazy(() => import('./RoadmapRender')); |
||||||
|
|
||||||
|
export function App() { |
||||||
|
const [show, setShow] = useState(false); |
||||||
|
return ( |
||||||
|
<> |
||||||
|
<button onClick={() => setShow(true)}>Show</button> |
||||||
|
{show && ( |
||||||
|
<Suspense fallback={<div>Loading...</div>}> |
||||||
|
<LazyRoadmapRender /> |
||||||
|
</Suspense> |
||||||
|
)} |
||||||
|
</> |
||||||
|
); |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
Until the `RoadmapRender` component is loaded, the `Suspense` component will display the `Loading...` fallback content. |
@ -0,0 +1,67 @@ |
|||||||
|
`useTransition` hook allows you to mark certain updates as **transitions** so they can be deprioritized, allowing other, more urgent updates to be processed first. This ensures that the UI remains responsive during updates that might take some time. |
||||||
|
|
||||||
|
```js |
||||||
|
import { useTransition, useState } from 'react'; |
||||||
|
import { Posts } from './Posts'; |
||||||
|
import { Home } from './Home'; |
||||||
|
import { Contact } from './Contact'; |
||||||
|
|
||||||
|
export function App() { |
||||||
|
const [isPending, startTransition] = useTransition(); |
||||||
|
const [page, setPage] = useState('home'); |
||||||
|
|
||||||
|
function changePage(newPage: string) { |
||||||
|
startTransition(() => { |
||||||
|
setPage(newPage); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<> |
||||||
|
<button onClick={() => changePage('home')}>Home</button> |
||||||
|
<button onClick={() => changePage('posts')}>Posts</button> |
||||||
|
<button onClick={() => changePage('contact')}>Contact</button> |
||||||
|
<hr /> |
||||||
|
{isPending && <div>Loading...</div>} |
||||||
|
{page === 'home' && <Home />} |
||||||
|
{page === 'posts' && <Posts />} |
||||||
|
{page === 'contact' && <Contact />} |
||||||
|
</> |
||||||
|
); |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
```js |
||||||
|
export function Home() { |
||||||
|
return <div>Home</div>; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
```js |
||||||
|
export function Contact() { |
||||||
|
return <div>Contact</div>; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
Posts component is artificially delayed by 500ms to emulate extremely slow code. |
||||||
|
|
||||||
|
```js |
||||||
|
export function Posts() { |
||||||
|
const items = []; |
||||||
|
for (let i = 0; i < 500; i++) { |
||||||
|
items.push(<SlowPost key={i} />); |
||||||
|
} |
||||||
|
return <ul>{items}</ul>; |
||||||
|
} |
||||||
|
|
||||||
|
function SlowPost() { |
||||||
|
const startTime = performance.now(); |
||||||
|
while (performance.now() - startTime < 1) { |
||||||
|
// Do nothing for 1 ms per item to emulate extremely slow code |
||||||
|
} |
||||||
|
|
||||||
|
return <li>Post</li>; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
Now when you click on the `Posts` button, you'll notice that the UI remains responsive and you can still switch to other pages while the posts are loading. Try removing the `startTransition` wrapper around `setPage` in `changePage` to see the difference. |
Loading…
Reference in new issue