Skip to content

Commit 8e2b802

Browse files
committed
finish exercise 1
1 parent fbaa2b1 commit 8e2b802

File tree

4 files changed

+100
-0
lines changed

4 files changed

+100
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -1 +1,9 @@
11
# Controlling Inputs
2+
3+
👨‍💼 Great! Now you can add/remove each of these tags to the search when they're
4+
checked. Programmatically controlling the input value is why you use the `value`
5+
prop.
6+
7+
But the feature is incomplete because a user could manually type the tag into
8+
the search input and it would not be reflected in the checkbox. Let's look at
9+
that next.
Original file line numberDiff line numberDiff line change
@@ -1 +1,70 @@
11
# Derive State
2+
3+
🦉 Often, it can be easy to think you need to keep track of two elements of
4+
state when you really only need one. For example, let's say you have a counter
5+
that will display the number of times a user has clicked a button and also it
6+
will display whether that number is odd or even. You might be tempted to write
7+
the following code:
8+
9+
```tsx
10+
import { useState } from 'react'
11+
12+
export default function Counter() {
13+
const [count, setCount] = useState(0)
14+
const [isEven, setIsEven] = useState(true)
15+
16+
function handleClick() {
17+
const newCount = count + 1
18+
setCount(newCount)
19+
setIsEven(newCount % 2 === 0)
20+
}
21+
22+
return (
23+
<div>
24+
<p>{count}</p>
25+
<p>{isEven ? 'Even' : 'Odd'}</p>
26+
<button onClick={handleClick}>Increment</button>
27+
</div>
28+
)
29+
}
30+
```
31+
32+
This code works, but it's not ideal because it's keeping track of two pieces of
33+
state when it only needs to keep track of one. Imagine if we had multiple places
34+
where the count could be changed. We'd have to remember to update the `isEven`
35+
state in all of those places. This is a recipe for bugs.
36+
37+
Instead, we can derive the `isEven` state from the `count` state:
38+
39+
```tsx
40+
import { useState } from 'react'
41+
42+
export default function Counter() {
43+
const [count, setCount] = useState(0)
44+
45+
function handleClick() {
46+
const newCount = count + 1
47+
setCount(newCount)
48+
}
49+
50+
// this is the derived state
51+
const isEven = count % 2 === 0
52+
53+
return (
54+
<div>
55+
<p>{count}</p>
56+
<p>{isEven ? 'Even' : 'Odd'}</p>
57+
<button onClick={handleClick}>Increment</button>
58+
</div>
59+
)
60+
}
61+
```
62+
63+
This is a much better solution because we only have to keep track of the `count`
64+
state. The `isEven` state is derived from the `count` state. This means we don't
65+
have to worry about keeping the `isEven` state in sync with the `count` state.
66+
67+
👨‍💼 Thanks Olivia! So what we want to do in this step is derive the checkboxes'
68+
`checked` state based on whether the query contains the word they represent.
69+
70+
Give that a shot.
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
11
# Derive State
2+
3+
👨‍💼 Awesome work! It looks really cool to have the checkboxes check and uncheck
4+
automatically as you type! We're now controlling both all the inputs on here
5+
all based on a single element of state. Well done.
+19
Original file line numberDiff line numberDiff line change
@@ -1 +1,20 @@
11
# Initialize State
2+
3+
👨‍💼 We want users to be able to share a link to this page with a prefilled
4+
search. For example:
5+
[`https://www.example.com/search?query=cat+dog`](/app/playground?query=cat+dog).
6+
7+
Right now, this won't work, because we don't have a way to initialize the
8+
state of the search box from the URL. Let's fix that.
9+
10+
The `useState` hook supports an initial value. Right now we're just passing
11+
`''` as the initial value, but we can use the `URLSearchParams` API to get the
12+
query string from the URL and use that as the initial value.
13+
14+
```tsx
15+
const params = new URLSearchParams(window.location.search)
16+
const initialQuery = params.get('query') ?? ''
17+
```
18+
19+
Then you can pass that `initialQuery` to `useState`. Give that a shot and then
20+
the link above should work!

0 commit comments

Comments
 (0)