mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-05-28 18:26:54 +00:00
fix(curriculum): react code block identifier (#60764)
Co-authored-by: Huyen Nguyen <25715018+huyenltnguyen@users.noreply.github.com>
This commit is contained in:
+7
-7
@@ -24,7 +24,7 @@ This UI is described using JSX, a syntax extension for JavaScript that looks sim
|
||||
|
||||
Let's look at an example of a React component:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function Greeting() {
|
||||
const name = "John"
|
||||
{/* The result will be Hello John*/}
|
||||
@@ -42,7 +42,7 @@ Well, this is because in JavaScript, `class` is a reserved name. So, we need to
|
||||
|
||||
We are also using a comment in JSX showing what the result will be. It is important to note that you can use regular comment syntax like this but it needs to be wrapped in curly braces in order for it to work:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
{/* Block Comments */}
|
||||
```
|
||||
|
||||
@@ -54,7 +54,7 @@ When React encounters a lowercase tag, like `<div>` or `<span>`, it assumes it's
|
||||
|
||||
To use this `Greeting` component in our application, we would write something like this:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
<Greeting />
|
||||
```
|
||||
|
||||
@@ -62,7 +62,7 @@ This would render an `h1` element with the text `Hello John` to the page. But ta
|
||||
|
||||
When working with JSX, all tags and uses of components need to be explicitly closed. So if the component or tag does not have any children, then you need to explicitly close it like shown here:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
<Greeting /> {/* /> is required */}
|
||||
```
|
||||
|
||||
@@ -70,7 +70,7 @@ So far we have only been looking at how to render a single `h1` element. But you
|
||||
|
||||
Let’s take a look at the following example code here:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function Greeting() {
|
||||
const name = "John";
|
||||
{/* This will throw an error */}
|
||||
@@ -87,7 +87,7 @@ The reason why you are getting that error message is because multiple sibling el
|
||||
|
||||
React fragments are used to group elements together. Here is what the revised example will look like:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function Greeting() {
|
||||
const name = "John";
|
||||
return (
|
||||
@@ -101,7 +101,7 @@ function Greeting() {
|
||||
|
||||
You can also choose to use empty JSX tags which can serve as shorthand for fragments:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function Greeting() {
|
||||
const name = "John";
|
||||
return (
|
||||
|
||||
+10
-10
@@ -20,7 +20,7 @@ In this example, we have a `Cat` component that belongs in a file called `Cat.js
|
||||
|
||||
This `Cat` component returns a JSX markup with a title and image for a cat called Mr. Whiskers:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function Cat() {
|
||||
return (
|
||||
<div className="card">
|
||||
@@ -36,7 +36,7 @@ function Cat() {
|
||||
|
||||
If we want to use our `Cat` component in another file, we need to first export it like this:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function Cat() {
|
||||
return (
|
||||
<div className="card">
|
||||
@@ -54,7 +54,7 @@ export default Cat;
|
||||
|
||||
We are using the `default` keyword because this will be the default export from the module. You can also choose to export the component on the same line as the component definition like this:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
export default function Cat() {
|
||||
return (
|
||||
<div className="card">
|
||||
@@ -72,7 +72,7 @@ You can choose to import child components in other parent component files, or im
|
||||
|
||||
Every React project will have a top-level component, typically called `App.jsx`:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
export default function App() {
|
||||
return (
|
||||
// return component here
|
||||
@@ -84,7 +84,7 @@ This file is usually located in the `src` directory of your project. You’ll le
|
||||
|
||||
To use the `Cat` component inside the root `App` component, you will need to import it like this:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
import Cat from "./Cat";
|
||||
|
||||
export default function App() {
|
||||
@@ -96,7 +96,7 @@ export default function App() {
|
||||
|
||||
Now, you can return the `Cat` component inside the `App` component like this:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
import Cat from "./Cat";
|
||||
|
||||
export default function App() {
|
||||
@@ -116,7 +116,7 @@ Which of the following is the correct way to export a React component?
|
||||
|
||||
## --answers--
|
||||
|
||||
```js
|
||||
```jsx
|
||||
export default function Cat() {
|
||||
return (
|
||||
<div className="card">
|
||||
@@ -132,7 +132,7 @@ export default function Cat() {
|
||||
|
||||
---
|
||||
|
||||
```js
|
||||
```jsx
|
||||
exportComponent function Cat() {
|
||||
return (
|
||||
<div className="card">
|
||||
@@ -152,7 +152,7 @@ Review the middle of the video where this was discussed.
|
||||
|
||||
---
|
||||
|
||||
```js
|
||||
```jsx
|
||||
e.default function Cat() {
|
||||
return (
|
||||
<div className="card">
|
||||
@@ -172,7 +172,7 @@ Review the middle of the video where this was discussed.
|
||||
|
||||
---
|
||||
|
||||
```js
|
||||
```jsx
|
||||
default function Cat() {
|
||||
return (
|
||||
<div className="card">
|
||||
|
||||
+6
-6
@@ -38,7 +38,7 @@ If you check the `package.json` file, you will see that `react-router` was added
|
||||
|
||||
Then inside of your `main.jsx` or `index.jsx` file, you will need to import `BrowserRouter` and render `BrowserRouter` around your `App` component:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { BrowserRouter } from "react-router";
|
||||
@@ -63,7 +63,7 @@ import { BrowserRouter, Routes, Route } from "react-router";
|
||||
|
||||
Then inside of the `BrowserRouter`, add the `Routes` and `Route` components:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
createRoot(document.getElementById("root")).render(
|
||||
<StrictMode>
|
||||
<BrowserRouter>
|
||||
@@ -79,7 +79,7 @@ The `path` and `element` are used to couple the URL and UI components together.
|
||||
|
||||
It is common in larger applications to have multiple views and routes setup like this:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
<Routes>
|
||||
<Route index element={<Home />} />
|
||||
<Route path="about" element={<About />} />
|
||||
@@ -97,7 +97,7 @@ The `index` prop in these examples is meant to represent the default route for a
|
||||
|
||||
You may have also noticed that we are nesting a few routes inside another route like this:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
<Route path="products">
|
||||
<Route path="trending" element={<Trending />} />
|
||||
</Route>
|
||||
@@ -107,7 +107,7 @@ This means that the path of the child route will be appended to the parent route
|
||||
|
||||
If the `path` begins with a colon (`:`) then that represents a dynamic segment in the route:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
<Route path=":category" element={<Category />} />
|
||||
```
|
||||
|
||||
@@ -115,7 +115,7 @@ In this example we have a dynamic segment called `category`. When a user navigat
|
||||
|
||||
You can access the value of the dynamic segment by using the `useParams` hook inside the child component like this:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
import { useParams } from "react-router";
|
||||
|
||||
export default function Category() {
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ Another feature of Next.js are the automatic image and font optimizations.
|
||||
|
||||
Here is an example of working with the `Image` component inside a `page.js` file:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
import Image from "next/image";
|
||||
|
||||
export default function Page() {
|
||||
|
||||
+2
-2
@@ -36,7 +36,7 @@ const sectionRef = useRef(null);
|
||||
|
||||
The final thing to do is to attach the ref variable to the element in your JSX by using the `ref` attribute:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
<section ref={sectionRef}>
|
||||
{/* Section content */}
|
||||
</section>
|
||||
@@ -64,7 +64,7 @@ A typical example to showcase a ref is to focus an input element on render, or b
|
||||
|
||||
Here's how to do that when you click a button:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
import { useRef } from "react";
|
||||
|
||||
const Focus = () => {
|
||||
|
||||
+6
-6
@@ -32,7 +32,7 @@ Then you use it as a function, like this:
|
||||
|
||||
```js
|
||||
useEffect(() => {
|
||||
// Your side effect logic (usually a function) here
|
||||
// Your side effect logic (usually a function) here
|
||||
}, [dependencies]);
|
||||
```
|
||||
|
||||
@@ -48,7 +48,7 @@ Note that `dependencies` can be an array of "reactive values" (state, props, fun
|
||||
|
||||
For example, in this `Counter` application, we don't pass in a `dependencies` argument, so the effect runs when the component renders and every time it updates:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
import { useState, useEffect } from "react";
|
||||
|
||||
const Counter = () => {
|
||||
@@ -103,10 +103,10 @@ Here's the syntax for returning a cleanup function from the `useEffect` hook:
|
||||
|
||||
```js
|
||||
useEffect(() => {
|
||||
// Your side effect logic here
|
||||
return () => {
|
||||
// Cleanup logic here (optional)
|
||||
};
|
||||
// Your side effect logic here
|
||||
return () => {
|
||||
// Cleanup logic here (optional)
|
||||
};
|
||||
}, [dependencies]);
|
||||
```
|
||||
|
||||
|
||||
+15
-15
@@ -80,20 +80,20 @@ To use this hook, we've prepared a `footballers` array to filter through with a
|
||||
|
||||
```js
|
||||
const footballers = [
|
||||
'Lionel Messi', 'Cristiano Ronaldo', 'Neymar Jr',
|
||||
'Kylian Mbappe', 'Mohamed Salah', 'Sadio Mane',
|
||||
'Kevin De Bruyne', 'Robert Lewandowski', 'Harry Kane',
|
||||
'Sergio Ramos', 'Virgil van Dijk', 'Alisson Becker',
|
||||
'Joshua Kimmich', 'Manuel Neuer', 'Karim Benzema',
|
||||
'Thibaut Courtois', 'Eden Hazard', 'Raheem Sterling',
|
||||
'Bruno Fernandes', 'Trent Alexander-Arnold', 'Son Heung-min',
|
||||
'Pierre-Emerick Aubameyang','Sergio Aguero', 'Luis Suarez',
|
||||
'Luka Modric', 'Casemiro', 'Frenkie de Jong', 'Gerard Pique',
|
||||
'Marc-Andre ter Stegen', 'Keylor Navas', 'Angel Di Maria',
|
||||
"N'Golo Kante", 'Kai Havertz', 'Timo Werner', 'Hakim Ziyech',
|
||||
'Christian Pulisic', 'Mason Mount', 'Olivier Giroud', 'Tammy Abraham',
|
||||
'Kepa Arrizabalaga', 'Ben Chilwell', 'Thiago Silva', 'Kurt Zouma',
|
||||
'John Terry', 'Didier Drogba', 'Frank Lampard', 'Ashley Cole', 'Petr Cech',
|
||||
'Lionel Messi', 'Cristiano Ronaldo', 'Neymar Jr',
|
||||
'Kylian Mbappe', 'Mohamed Salah', 'Sadio Mane',
|
||||
'Kevin De Bruyne', 'Robert Lewandowski', 'Harry Kane',
|
||||
'Sergio Ramos', 'Virgil van Dijk', 'Alisson Becker',
|
||||
'Joshua Kimmich', 'Manuel Neuer', 'Karim Benzema',
|
||||
'Thibaut Courtois', 'Eden Hazard', 'Raheem Sterling',
|
||||
'Bruno Fernandes', 'Trent Alexander-Arnold', 'Son Heung-min',
|
||||
'Pierre-Emerick Aubameyang','Sergio Aguero', 'Luis Suarez',
|
||||
'Luka Modric', 'Casemiro', 'Frenkie de Jong', 'Gerard Pique',
|
||||
'Marc-Andre ter Stegen', 'Keylor Navas', 'Angel Di Maria',
|
||||
"N'Golo Kante", 'Kai Havertz', 'Timo Werner', 'Hakim Ziyech',
|
||||
'Christian Pulisic', 'Mason Mount', 'Olivier Giroud', 'Tammy Abraham',
|
||||
'Kepa Arrizabalaga', 'Ben Chilwell', 'Thiago Silva', 'Kurt Zouma',
|
||||
'John Terry', 'Didier Drogba', 'Frank Lampard', 'Ashley Cole', 'Petr Cech',
|
||||
];
|
||||
|
||||
export default footballers;
|
||||
@@ -101,7 +101,7 @@ export default footballers;
|
||||
|
||||
And here's a `FootballerSearch` component that uses the `useDebounce` hook to delay searching for 1 second after the user stops typing:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
import { useState, useEffect } from "react";
|
||||
import { useDebounce } from "./hooks/useDebounce";
|
||||
import footballers from "./footballers";
|
||||
|
||||
+49
-49
@@ -88,7 +88,7 @@ You can then go ahead and use all of those states to render the data from the AP
|
||||
|
||||
Here's the full code:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
import { useState, useEffect } from "react";
|
||||
|
||||
const FetchPosts = () => {
|
||||
@@ -209,34 +209,34 @@ Note that the "fetcher" name here is only a convention, so you're free to name t
|
||||
|
||||
Here's a component fetching todos from the JSON Placeholder API:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
import useSWR from "swr";
|
||||
|
||||
const fetcher = (url) => fetch(url).then((res) => res.json());
|
||||
|
||||
const FetchTodos = () => {
|
||||
const { data, error } = useSWR(
|
||||
"https://jsonplaceholder.typicode.com/todos",
|
||||
fetcher
|
||||
);
|
||||
const { data, error } = useSWR(
|
||||
"https://jsonplaceholder.typicode.com/todos",
|
||||
fetcher
|
||||
);
|
||||
|
||||
if (!data) {
|
||||
return <h2>Loading...</h2>;
|
||||
}
|
||||
if (error) {
|
||||
return <h2>Error: {error.message}</h2>;
|
||||
}
|
||||
if (!data) {
|
||||
return <h2>Loading...</h2>;
|
||||
}
|
||||
if (error) {
|
||||
return <h2>Error: {error.message}</h2>;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2>Todos</h2>
|
||||
<div>
|
||||
{data.map((todo) => (
|
||||
<h3 key={todo.id}>{todo.title}</h3>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<h2>Todos</h2>
|
||||
<div>
|
||||
{data.map((todo) => (
|
||||
<h3 key={todo.id}>{todo.title}</h3>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default FetchTodos;
|
||||
@@ -246,19 +246,19 @@ As you learned in a previous lecture on custom hooks, data fetching is a logic y
|
||||
|
||||
Here's a `useFetch` hook that uses SWR for data fetching:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
import useSWR from "swr";
|
||||
|
||||
const fetcher = (url) => fetch(url).then((res) => res.json());
|
||||
|
||||
const useFetch = (url) => {
|
||||
const { data, error } = useSWR(url, fetcher);
|
||||
const { data, error } = useSWR(url, fetcher);
|
||||
|
||||
return {
|
||||
data,
|
||||
loading: !data && !error,
|
||||
error,
|
||||
};
|
||||
return {
|
||||
data,
|
||||
loading: !data && !error,
|
||||
error,
|
||||
};
|
||||
};
|
||||
|
||||
export default useFetch;
|
||||
@@ -266,32 +266,32 @@ export default useFetch;
|
||||
|
||||
And here's how to use the `useFetch` hook to rewrite the first example that fetches posts from the JSON Placeholder API:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
import useFetch from "./useFetch";
|
||||
|
||||
const FetchPosts = () => {
|
||||
const { data, loading, error } = useFetch(
|
||||
"https://jsonplaceholder.typicode.com/posts"
|
||||
);
|
||||
const { data, loading, error } = useFetch(
|
||||
"https://jsonplaceholder.typicode.com/posts"
|
||||
);
|
||||
|
||||
if (loading) {
|
||||
return <h2>Loading...</h2>;
|
||||
}
|
||||
if (loading) {
|
||||
return <h2>Loading...</h2>;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return <h2>{error.message}</h2>;
|
||||
}
|
||||
if (error) {
|
||||
return <h2>{error.message}</h2>;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2>Posts</h2>
|
||||
<ul>
|
||||
{data.map((post) => (
|
||||
<li key={post.id}>{post.title}</li>
|
||||
))}
|
||||
</ul>
|
||||
</>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<h2>Posts</h2>
|
||||
<ul>
|
||||
{data.map((post) => (
|
||||
<li key={post.id}>{post.title}</li>
|
||||
))}
|
||||
</ul>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default FetchPosts;
|
||||
|
||||
+17
-17
@@ -48,10 +48,10 @@ Let's see how to use the `useMemo` hook first. Here's the basic syntax of the `u
|
||||
|
||||
```js
|
||||
const memoizedValue = useMemo(
|
||||
function () {
|
||||
return computeExpensiveValue(a, b);
|
||||
},
|
||||
[a, b]
|
||||
function () {
|
||||
return computeExpensiveValue(a, b);
|
||||
},
|
||||
[a, b]
|
||||
);
|
||||
```
|
||||
|
||||
@@ -59,26 +59,26 @@ You can see all that's needed is to wrap the `useMemo` hook around the function.
|
||||
|
||||
This `ExpensiveSquare` component will receive a `num` prop which it will use to calculate the square:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function ExpensiveSquare({ num }) {
|
||||
function calculateSquare(n) {
|
||||
console.log("Calculating square...");
|
||||
return n * n;
|
||||
}
|
||||
function calculateSquare(n) {
|
||||
console.log("Calculating square...");
|
||||
return n * n;
|
||||
}
|
||||
|
||||
const squared = calculateSquare(num);
|
||||
return (
|
||||
<p>
|
||||
Square of {num}: {squared}
|
||||
</p>
|
||||
);
|
||||
const squared = calculateSquare(num);
|
||||
return (
|
||||
<p>
|
||||
Square of {num}: {squared}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
export default ExpensiveSquare;
|
||||
```
|
||||
|
||||
Here's the `App` component where the `ExpensiveSquare` is being used:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
import { useState, useEffect } from "react";
|
||||
import ExpensiveSquare from "./components/ExpensiveSquare";
|
||||
|
||||
@@ -107,7 +107,7 @@ The `timer` in the `useEffect`, running every second, will make the `calculateSq
|
||||
|
||||
To solve this problem, we can use the `useMemo` hook by wrapping the function call in it and specifying the `num` variable as the dependency:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
// import the useMemo hook
|
||||
import { useMemo } from "react";
|
||||
|
||||
|
||||
+7
-7
@@ -32,7 +32,7 @@ const handleClick = useCallback(() => {
|
||||
|
||||
And here's the basic syntax of `React.memo`:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
const MemoizedComponent = React.memo(({ prop }) => {
|
||||
return (
|
||||
<>
|
||||
@@ -44,7 +44,7 @@ const MemoizedComponent = React.memo(({ prop }) => {
|
||||
|
||||
Let's look at an example of the `useCallback` hook:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
import { useState, useEffect } from "react";
|
||||
|
||||
function Counter() {
|
||||
@@ -73,7 +73,7 @@ In the component, the effect runs any time `handleClick` changes because the `ha
|
||||
|
||||
To fix this, you need to tell React to treat the `handleClick` function as the same thing across renders by memoizing it with the `useCallback` hook, so it doesn't get recreated:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
|
||||
function Counter() {
|
||||
@@ -103,7 +103,7 @@ Now the `handleClick` function is not being recreated on every render.
|
||||
|
||||
To show you how the `React.memo` (or `memo`) higher-order function works and the `useCallback` hook work in tandem, here's a `Counter` component with a `handleClick` function that needs `useCallback` but is currently not using it:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
import CounterChild from "./CounterChild";
|
||||
|
||||
@@ -142,7 +142,7 @@ That's why the `handleClick` needs to be memoized with `useCallback`.
|
||||
|
||||
Here's the `CounterChild` component:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
const CounterChild = ({ onClick }) => {
|
||||
console.log("CounterChild component rendered");
|
||||
return <button onClick={onClick}>Increment from Child</button>;
|
||||
@@ -159,7 +159,7 @@ Without memoization, because as the component re-renders due to the timer updati
|
||||
|
||||
To prevent this, you need to memoize the `CounterChild` component with `React.memo`:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
import React from "react";
|
||||
|
||||
const CounterChild = React.memo(({ onClick }) => {
|
||||
@@ -246,7 +246,7 @@ The second argument should be an array of dependencies.
|
||||
|
||||
---
|
||||
|
||||
```js
|
||||
```jsx
|
||||
const handleClick = useCallback(() => { /* code */ }, [dependency]);
|
||||
```
|
||||
|
||||
|
||||
+3
-3
@@ -58,7 +58,7 @@ export async function saveTask(task) {
|
||||
|
||||
Here's the code that sets up the `useOptimistic` hook by importing and initializing it, with an `handleSubmit` function that sends an input to the action:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
"use client";
|
||||
|
||||
import { useOptimistic } from "react";
|
||||
@@ -91,7 +91,7 @@ When the form is submitted, the `handleSubmit` function extracts the task and ad
|
||||
|
||||
Here's the `TaskList` component:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
"use client";
|
||||
import { useOptimistic, startTransition } from "react";
|
||||
|
||||
@@ -150,7 +150,7 @@ Here, we are looping through the `optimisticTask` parameter to display the task.
|
||||
|
||||
Here's the `Task` component that manages the state for the form. It calls the `saveTask` function from the action so it can add the task, and appends the new task once it is received by the server:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
|
||||
+7
-7
@@ -16,7 +16,7 @@ How do you pass props from a parent component to a child component in react?
|
||||
|
||||
In the previous lectures, we learned how to build small components in React like this:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function Greeting() {
|
||||
const developerName = "Jessica";
|
||||
return <h1>Hi {developerName}!</h1>;
|
||||
@@ -25,7 +25,7 @@ function Greeting() {
|
||||
|
||||
We can choose to nest this component inside another parent component or the root component like this:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function App() {
|
||||
return <Greeting />;
|
||||
}
|
||||
@@ -42,7 +42,7 @@ What if we wanted to display a different name like Naomi, Tom, or Oliver? This i
|
||||
|
||||
Let's update our example from earlier to now accept a `name` prop:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function App() {
|
||||
return <Greeting name="Jessica" />;
|
||||
}
|
||||
@@ -61,7 +61,7 @@ Then, inside of the parent `App` component, we are passing the value to the `nam
|
||||
|
||||
Now we have the ability to reuse the child component several times and pass in different names each time:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function App() {
|
||||
return (
|
||||
<>
|
||||
@@ -76,7 +76,7 @@ function App() {
|
||||
|
||||
You can also choose to use object destructuring in the props to make it more readable. Here's how you could rewrite the `Greeting` component:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function Greeting({ name }) {
|
||||
return <h1>Hi {name}!</h1>;
|
||||
}
|
||||
@@ -88,7 +88,7 @@ Sometimes, you can have a lot of properties that you have to pass as props. Inst
|
||||
|
||||
Here is an example of a new child component called `DeveloperCard`:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function DeveloperCard({ name, age, country }) {
|
||||
return (
|
||||
<div className="developer-card">
|
||||
@@ -104,7 +104,7 @@ This `DeveloperCard` component accepts three props: `name`, `age`, and `country`
|
||||
|
||||
In the parent `App` component, we can use the spread syntax to pass all the properties from an object as individual props to the child component:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function App() {
|
||||
const developerObj = {
|
||||
name: "Alice",
|
||||
|
||||
+6
-6
@@ -20,7 +20,7 @@ The most common approaches of using conditional rendering includes using `if` st
|
||||
|
||||
The simplest form of conditional rendering uses an `if` statement. Here's an example:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function Greeting({ isLoggedIn }) {
|
||||
if (isLoggedIn) {
|
||||
return <h1>Welcome back!</h1>;
|
||||
@@ -33,7 +33,7 @@ In this example, the `Greeting` component checks the `isLoggedIn` prop. If it's
|
||||
|
||||
Here is an example using the `Greeting` component inside of the parent `App` component:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function App() {
|
||||
return (
|
||||
<div className="App">
|
||||
@@ -45,7 +45,7 @@ function App() {
|
||||
|
||||
For simpler conditions, the ternary operator (`?:`) is often used directly within JSX. It allows for inline conditional rendering, which can make your code more concise:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function Greeting({ isLoggedIn }) {
|
||||
return <h1>{isLoggedIn ? "Welcome back!" : "Please sign in."}</h1>;
|
||||
}
|
||||
@@ -55,7 +55,7 @@ This code achieves the same result as the previous example but in a more compact
|
||||
|
||||
Another common pattern for conditional rendering is using the logical AND (`&&`) operator. This is particularly useful when you want to render something, or nothing, based on a condition:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function Notification({ message }) {
|
||||
return (
|
||||
<div>
|
||||
@@ -111,7 +111,7 @@ Using the `switch` statement.
|
||||
|
||||
What will be rendered by the following code if `message` is an empty string?
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function Alert({ message }) {
|
||||
return (
|
||||
<div>
|
||||
@@ -157,7 +157,7 @@ Consider how the logical AND (`&&`) operator works with falsy values in JSX.
|
||||
|
||||
In the following code, what type of conditional rendering is being used?
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function Greeting({ name }) {
|
||||
return <h1>{name ? `Hello, ${name}!` : 'Hello, Guest!'}</h1>;
|
||||
}
|
||||
|
||||
+3
-3
@@ -18,7 +18,7 @@ Rendering lists is a fundamental task in React web apps, and is used for display
|
||||
|
||||
Here is an example of a component called `FruitList` that displays a list of fruits:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function FruitList() {
|
||||
const fruits = ['Apple', 'Banana', 'Cherry', 'Date'];
|
||||
return (
|
||||
@@ -35,7 +35,7 @@ However, when rendering lists in React, it is important not to forget the `key`
|
||||
|
||||
Let's modify our example to include keys:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function FruitList() {
|
||||
const fruits = ["Apple", "Banana", "Cherry", "Date"];
|
||||
return (
|
||||
@@ -52,7 +52,7 @@ In this refactored example, we are creating a unique key for each list item by c
|
||||
|
||||
React also allows you to render more complex structures. For instance, you might have an array of objects representing users, each with multiple properties that you want to display:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function UserList() {
|
||||
const users = [
|
||||
{ id: "user-001-employee", name: "Alice", email: "alice@example.com" },
|
||||
|
||||
+3
-3
@@ -20,7 +20,7 @@ React's approach to inline styles involves using JavaScript objects to define st
|
||||
|
||||
Here is an example of how you can use inline styles for a `Button` component:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function Button({ buttonText }) {
|
||||
const defaultStyles = {
|
||||
backgroundColor: "#007BFF",
|
||||
@@ -42,7 +42,7 @@ In this example, we define a style object called `defaultStyles`. We then apply
|
||||
|
||||
You can also choose to pass in an object directly to the `style` attribute. Here is what a revised example would look like:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function Button({ buttonText }) {
|
||||
return (
|
||||
<button
|
||||
@@ -63,7 +63,7 @@ It's important to note that while CSS property names are typically written in ke
|
||||
|
||||
A great advantage of inline styles in React is that they support dynamic styling based on a component state or props. For example:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function DynamicButton({ isActive }) {
|
||||
const buttonStyles = {
|
||||
backgroundColor: isActive ? "green" : "red",
|
||||
|
||||
+14
-14
@@ -24,7 +24,7 @@ Controlled input is the most "React-like" way to handle form inputs. With contro
|
||||
|
||||
The process works like this: React maintains the form state with the `useState` hook, and you update it on every change. When a user types in an input field, the `onChange` event fires, updates the state, and React re-renders the component with the new value.
|
||||
|
||||
```js
|
||||
```jsx
|
||||
import { useState } from "react";
|
||||
|
||||
function App() {
|
||||
@@ -69,24 +69,24 @@ Since the DOM controls the input values, what you need is to pull in the values
|
||||
|
||||
Here's an example of uncontrolled inputs:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
import { useRef } from "react";
|
||||
|
||||
function App() {
|
||||
const nameRef = useRef();
|
||||
const nameRef = useRef();
|
||||
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
console.log(nameRef.current.value);
|
||||
};
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
console.log(nameRef.current.value);
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<label htmlFor="name">Your</label>{" "}
|
||||
<input type="text" ref={nameRef} id="name" />
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
);
|
||||
return (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<label htmlFor="name">Your</label>{" "}
|
||||
<input type="text" ref={nameRef} id="name" />
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
||||
+101
-101
@@ -26,8 +26,8 @@ A server action looks like this:
|
||||
"use server";
|
||||
|
||||
async function submitForm(formData) {
|
||||
const name = formData.get("name");
|
||||
return { message: `Hello, ${name}!` };
|
||||
const name = formData.get("name");
|
||||
return { message: `Hello, ${name}!` };
|
||||
}
|
||||
```
|
||||
|
||||
@@ -67,26 +67,26 @@ To use the `useActionState` hook, make sure you have an action in place first. L
|
||||
"use server";
|
||||
|
||||
export async function submitForm(_, formData) {
|
||||
const name = formData.get("name");
|
||||
const name = formData.get("name");
|
||||
|
||||
const hour = new Date().getHours();
|
||||
let greeting;
|
||||
const hour = new Date().getHours();
|
||||
let greeting;
|
||||
|
||||
if (hour < 12) {
|
||||
greeting = "Good morning";
|
||||
} else if (hour < 18) {
|
||||
greeting = "Good afternoon";
|
||||
} else {
|
||||
greeting = "Good evening";
|
||||
}
|
||||
if (hour < 12) {
|
||||
greeting = "Good morning";
|
||||
} else if (hour < 18) {
|
||||
greeting = "Good afternoon";
|
||||
} else {
|
||||
greeting = "Good evening";
|
||||
}
|
||||
|
||||
return { message: `${greeting}, ${name}` };
|
||||
return { message: `${greeting}, ${name}` };
|
||||
}
|
||||
```
|
||||
|
||||
In your component, you then need to import the `useActionState` hook and call it at the top level of the component body (before the return statement) just like other hooks. You should also import the action:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
"use client";
|
||||
|
||||
// Import the useActionState hook
|
||||
@@ -102,11 +102,11 @@ const Greeter = () => {
|
||||
message: "",
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center min-h-screen bg-gray-100 p-6">
|
||||
{/* Rest of component */}
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center min-h-screen bg-gray-100 p-6">
|
||||
{/* Rest of component */}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Greeter;
|
||||
@@ -114,51 +114,51 @@ export default Greeter;
|
||||
|
||||
Here's what the full code looks like with a bit of styling:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
"use client";
|
||||
|
||||
import { useActionState } from "react";
|
||||
import { submitForm } from "./actions/submitForm";
|
||||
|
||||
const Greeter = () => {
|
||||
const [state, submit, isPending] = useActionState(submitForm, {
|
||||
message: "",
|
||||
});
|
||||
const [state, submit, isPending] = useActionState(submitForm, {
|
||||
message: "",
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center min-h-screen bg-gray-100 p-6">
|
||||
<form
|
||||
action={submit}
|
||||
className="bg-white p-6 rounded-2xl shadow-md w-full max-w-md"
|
||||
>
|
||||
<h2 className="text-2xl text-center font-semibold text-gray-700 mb-4">
|
||||
Greet Someone
|
||||
</h2>
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center min-h-screen bg-gray-100 p-6">
|
||||
<form
|
||||
action={submit}
|
||||
className="bg-white p-6 rounded-2xl shadow-md w-full max-w-md"
|
||||
>
|
||||
<h2 className="text-2xl text-center font-semibold text-gray-700 mb-4">
|
||||
Greet Someone
|
||||
</h2>
|
||||
|
||||
<input
|
||||
type="text"
|
||||
name="name"
|
||||
placeholder="Enter your name"
|
||||
required
|
||||
className="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-green-400"
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
name="name"
|
||||
placeholder="Enter your name"
|
||||
required
|
||||
className="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-green-400"
|
||||
/>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isPending}
|
||||
className="w-full mt-4 p-3 bg-green-500 text-white font-semibold rounded-lg hover:bg-green-600 disabled:bg-gray-400 transition-all"
|
||||
>
|
||||
{isPending ? "Greeting..." : "Greet"}
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isPending}
|
||||
className="w-full mt-4 p-3 bg-green-500 text-white font-semibold rounded-lg hover:bg-green-600 disabled:bg-gray-400 transition-all"
|
||||
>
|
||||
{isPending ? "Greeting..." : "Greet"}
|
||||
</button>
|
||||
|
||||
{state.message && (
|
||||
<p className="mt-4 text-green-600 text-center font-medium">
|
||||
{state.message}
|
||||
</p>
|
||||
)}
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
{state.message && (
|
||||
<p className="mt-4 text-green-600 text-center font-medium">
|
||||
{state.message}
|
||||
</p>
|
||||
)}
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Greeter;
|
||||
@@ -174,44 +174,44 @@ In this example, we'll fetch five users from JSONPlaceholder with a button click
|
||||
"use server";
|
||||
|
||||
export async function getUsers() {
|
||||
const res = await fetch(
|
||||
"https://jsonplaceholder.typicode.com/users?_start=0&_limit=5/"
|
||||
);
|
||||
return await res.json();
|
||||
const res = await fetch(
|
||||
"https://jsonplaceholder.typicode.com/users?_start=0&_limit=5/"
|
||||
);
|
||||
return await res.json();
|
||||
}
|
||||
```
|
||||
|
||||
Here's the styled UI:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
"use client";
|
||||
|
||||
import { useActionState } from "react";
|
||||
import { getUsers } from "./actions/getUsers";
|
||||
|
||||
export default function FetchUsers() {
|
||||
const [users, fetchAction, isPending] = useActionState(getUsers, []);
|
||||
const [users, fetchAction, isPending] = useActionState(getUsers, []);
|
||||
|
||||
return (
|
||||
<div className="p-6 max-w-lg mx-auto">
|
||||
<button
|
||||
onClick={fetchAction}
|
||||
disabled={isPending}
|
||||
className="px-4 py-2 cursor-pointer bg-green-500 text-white rounded-lg hover:bg-green-600 disabled:bg-gray-400 font-bold"
|
||||
>
|
||||
{isPending ? "Fetching Users..." : "Fetch Users"}
|
||||
</button>
|
||||
return (
|
||||
<div className="p-6 max-w-lg mx-auto">
|
||||
<button
|
||||
onClick={fetchAction}
|
||||
disabled={isPending}
|
||||
className="px-4 py-2 cursor-pointer bg-green-500 text-white rounded-lg hover:bg-green-600 disabled:bg-gray-400 font-bold"
|
||||
>
|
||||
{isPending ? "Fetching Users..." : "Fetch Users"}
|
||||
</button>
|
||||
|
||||
<ul className="mt-4 space-y-2">
|
||||
{users.map((user) => (
|
||||
<li key={user.id} className="p-3 bg-gray-100 rounded-lg">
|
||||
<p className="font-semibold">{user.name}</p>
|
||||
<p className="text-sm text-gray-600">{user.email}</p>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
<ul className="mt-4 space-y-2">
|
||||
{users.map((user) => (
|
||||
<li key={user.id} className="p-3 bg-gray-100 rounded-lg">
|
||||
<p className="font-semibold">{user.name}</p>
|
||||
<p className="text-sm text-gray-600">{user.email}</p>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
@@ -221,7 +221,7 @@ This happens because React treats data fetching and rendering as a higher priori
|
||||
|
||||
To fix this issue, you need to wrap the action in `startTransition`:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
"use client";
|
||||
|
||||
import { useActionState } from "react";
|
||||
@@ -231,29 +231,29 @@ import { getUsers } from "./actions/getUsers";
|
||||
import { startTransition } from "react";
|
||||
|
||||
export default function FetchUsers() {
|
||||
const [users, fetchAction, isPending] = useActionState(getUsers, []);
|
||||
const [users, fetchAction, isPending] = useActionState(getUsers, []);
|
||||
|
||||
return (
|
||||
<div className="p-6 max-w-lg mx-auto">
|
||||
<button
|
||||
{/* wrap fetchAction in startTransition */}
|
||||
onClick={() => startTransition(() => fetchAction())}
|
||||
disabled={isPending}
|
||||
className="px-4 py-2 bg-green-500 font-bold cursor-pointer text-white rounded-lg hover:bg-green-600 disabled:bg-gray-400"
|
||||
>
|
||||
{isPending ? 'Fetching Users...' : 'Fetch Users'}
|
||||
</button>
|
||||
return (
|
||||
<div className="p-6 max-w-lg mx-auto">
|
||||
<button
|
||||
{/* wrap fetchAction in startTransition */}
|
||||
onClick={() => startTransition(() => fetchAction())}
|
||||
disabled={isPending}
|
||||
className="px-4 py-2 bg-green-500 font-bold cursor-pointer text-white rounded-lg hover:bg-green-600 disabled:bg-gray-400"
|
||||
>
|
||||
{isPending ? 'Fetching Users...' : 'Fetch Users'}
|
||||
</button>
|
||||
|
||||
<ul className="mt-4 space-y-2">
|
||||
{users.map((user) => (
|
||||
<li key={user.id} className="p-3 bg-gray-100 rounded-lg">
|
||||
<p className="font-semibold">{user.name}</p>
|
||||
<p className="text-sm text-gray-600">{user.email}</p>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
<ul className="mt-4 space-y-2">
|
||||
{users.map((user) => (
|
||||
<li key={user.id} className="p-3 bg-gray-100 rounded-lg">
|
||||
<p className="font-semibold">{user.name}</p>
|
||||
<p className="text-sm text-gray-600">{user.email}</p>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
+4
-4
@@ -90,7 +90,7 @@ In the code above, we have the `useState` hook imported from React. In the `Coun
|
||||
|
||||
You can manage multiple pieces of state by calling the `useState` hook multiple times. This is especially important when you have unrelated state variables:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function UserProfile() {
|
||||
const [isOnline, setIsOnline] = useState(false);
|
||||
const [notifications, setNotifications] = useState(0);
|
||||
@@ -101,7 +101,7 @@ function UserProfile() {
|
||||
|
||||
You can also call the `useState` hook multiple times when managing multiple states that update separately, like form fields:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function SignUpForm() {
|
||||
const [name, setName] = useState("");
|
||||
const [username, setUsername] = useState("");
|
||||
@@ -113,7 +113,7 @@ function SignUpForm() {
|
||||
|
||||
But in this case, it's best to combine the states since they're all part of the same form:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function SignUpForm() {
|
||||
const [formData, setFormData] = useState({
|
||||
name: "",
|
||||
@@ -249,7 +249,7 @@ Review the end of the video where the answer was discussed.
|
||||
|
||||
---
|
||||
|
||||
```js
|
||||
```jsx
|
||||
const [formData, setFormData] = useState({
|
||||
name: "",
|
||||
username: "",
|
||||
|
||||
+8
-8
@@ -167,31 +167,31 @@ Which of the following is NOT a valid attribute used for handling React events?
|
||||
|
||||
Which of the following is the correct way to update array state?
|
||||
|
||||
```jsx
|
||||
```js
|
||||
const [certificates, setCertificates] = useState([]);
|
||||
```
|
||||
|
||||
#### --distractors--
|
||||
|
||||
```jsx
|
||||
```js
|
||||
setCertificates(previousItems => previousItems, "Front End");
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```jsx
|
||||
```js
|
||||
setCertificates.push("Front End");
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```jsx
|
||||
```js
|
||||
setCertificates().append("Front End");
|
||||
```
|
||||
|
||||
#### --answer--
|
||||
|
||||
```jsx
|
||||
```js
|
||||
setCertificates(previousItems => [...previousItems, "Front End"]);
|
||||
```
|
||||
|
||||
@@ -201,7 +201,7 @@ setCertificates(previousItems => [...previousItems, "Front End"]);
|
||||
|
||||
What is wrong with this function?
|
||||
|
||||
```jsx
|
||||
```js
|
||||
function updateSpaceship() {
|
||||
setSpaceship(previousState => ({
|
||||
name: "Discovery"
|
||||
@@ -325,7 +325,7 @@ inputRef.current
|
||||
|
||||
How many times will this message be logged to the console?
|
||||
|
||||
```jsx
|
||||
```js
|
||||
useEffect(() => {
|
||||
console.log("Nice work!!");
|
||||
}, []);
|
||||
@@ -556,7 +556,7 @@ What is the purpose of the `dependencies` in a `useEffect`?
|
||||
|
||||
```js
|
||||
useEffect(() => {
|
||||
// Your side effect logic (usually a function) goes here
|
||||
// Your side effect logic (usually a function) goes here
|
||||
}, [dependencies]);
|
||||
```
|
||||
|
||||
|
||||
+2
-4
@@ -187,7 +187,7 @@ In the code above, the `h1` element is only rendered if the user object is truth
|
||||
|
||||
You can also use a direct `if` statement this way:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function Greeting({ isLoggedIn }) {
|
||||
if (isLoggedIn) {
|
||||
return <h1>Welcome back!</h1>;
|
||||
@@ -221,7 +221,7 @@ function NameList({ names }) {
|
||||
- Inline styles in React allow you to apply CSS styles directly to JSX elements using JavaScript objects.
|
||||
- To apply inline styles in React, you can use the style attribute on JSX elements. The style attribute takes an object where the keys are CSS properties in camelCase and the values are the corresponding values. Here's an example:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function Greeting() {
|
||||
return (
|
||||
<h1
|
||||
@@ -239,7 +239,6 @@ You can also extract the styles into a separate object and reference it in the `
|
||||
|
||||
```jsx
|
||||
function Greeting() {
|
||||
|
||||
const styles = {
|
||||
color: 'blue',
|
||||
fontSize: '24px',
|
||||
@@ -256,7 +255,6 @@ export default Greeting;
|
||||
|
||||
```jsx
|
||||
function Greeting({ isImportant }) {
|
||||
|
||||
const styles = {
|
||||
color: isImportant ? 'red' : 'black',
|
||||
fontSize: isImportant ? '24px' : '16px'
|
||||
|
||||
+9
-9
@@ -161,7 +161,7 @@ import axios from "axios";
|
||||
|
||||
Then you can fetch the data using `axios.get`:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
const [data, setData] = useState(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState(null);
|
||||
@@ -246,7 +246,7 @@ const [optimisticState, addOptimistic] = useOptimistic(actualState, updateFuncti
|
||||
|
||||
Here is an example of using the `useOptimistic` hook in a `TaskList` component:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
"use client";
|
||||
|
||||
import { useOptimistic } from "react";
|
||||
@@ -274,7 +274,7 @@ export default function TaskList({ tasks, addTask }) {
|
||||
- **`startTransition`**: This is used to render part of the UI and mark a state update as a non-urgent transition. This allows the UI to be responsive during expensive updates. Here is the basic syntax:
|
||||
|
||||
```js
|
||||
startTransition(action)
|
||||
startTransition(action);
|
||||
```
|
||||
|
||||
The `action` performs a state update or triggers some transition-related logic. This ensures that urgent UI updates (like typing or clicking) are not blocked.
|
||||
@@ -297,13 +297,13 @@ const memoizedSortedArray = useMemo(
|
||||
|
||||
```js
|
||||
const handleClick = useCallback(() => {
|
||||
// code goes here
|
||||
// code goes here
|
||||
}, [dependency]);
|
||||
```
|
||||
|
||||
- **`React.memo`**: This is used to memoize a component to prevent it from unnecessary re-renders when its prop has not changed.
|
||||
|
||||
```js
|
||||
```jsx
|
||||
const MemoizedComponent = React.memo(({ prop }) => {
|
||||
return (
|
||||
<>
|
||||
@@ -414,13 +414,13 @@ In this example we have a dynamic segment called `category`. When a user navigat
|
||||
|
||||
- **`useParams` Hook**: This hook is used to access the dynamic parameters from a URL path.
|
||||
|
||||
```js
|
||||
```jsx
|
||||
import { useParams } from "react-router";
|
||||
|
||||
export default function Category() {
|
||||
let params = useParams();
|
||||
{/* Accessing the category param: params.category */}
|
||||
{/* rest of code goes here */}
|
||||
{/* Accessing the category param: params.category */}
|
||||
{/* rest of code goes here */}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -460,7 +460,7 @@ export default function Page() {
|
||||
|
||||
- **Context API**: Context refers to when a parent component makes information available to child components without needing to pass it explicitly through props. `createContext` is used to create a context object which represent the context that other components will read. The `Provider` is used to supply context values to the child components.
|
||||
|
||||
```js
|
||||
```jsx
|
||||
import { useState, createContext } from "react";
|
||||
|
||||
const CounterContext = createContext();
|
||||
|
||||
+3
-3
@@ -135,7 +135,7 @@ export default Profile;
|
||||
|
||||
- **Updating Arrays in State**: When updating arrays in state, it is important not to directly modify the array using methods like `push()` or `pop()`. Instead you should create a new array when updating state:
|
||||
|
||||
```jsx
|
||||
```js
|
||||
const addItem = () => {
|
||||
const newItem = {
|
||||
id: items.length + 1,
|
||||
@@ -149,7 +149,7 @@ const addItem = () => {
|
||||
|
||||
If you want to remove items from an array, you should use the `filter()` method, which returns a new array after filtering out whatever you want to remove:
|
||||
|
||||
```jsx
|
||||
```js
|
||||
const removeItem = (id) => {
|
||||
setItems((prevItems) => prevItems.filter((item) => item.id !== id));
|
||||
};
|
||||
@@ -210,7 +210,7 @@ Note that `dependencies` can be an array of "reactive values" (state, props, fun
|
||||
|
||||
Here is an example of creating a `useDebounce` hook:
|
||||
|
||||
```jsx
|
||||
```js
|
||||
function useDebounce(value, delay) {
|
||||
const [debouncedValue, setDebouncedValue] = useState(value);
|
||||
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ You learned in the previous lecture videos that JSX is a syntax extension for Ja
|
||||
|
||||
Here is a remainder of what JSX looks like:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
const App = () => {
|
||||
return (
|
||||
<div>
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ Now that you have created the `isVisible` state variable, it is time to start us
|
||||
|
||||
In prior lecture videos, you learned about inline conditional rendering which allows you to show different content based on a certain condition. It is a common pattern to use the logical AND (`&&`) operator to conditionally render a piece of text like this:
|
||||
|
||||
```js
|
||||
```jsx
|
||||
function Notification({ message }) {
|
||||
return (
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user