Małe przypomnienie useState. Lekcja krótka i szybka, do dzieła.
Ok, łatwy przykład:
import { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<button onClick={handleClick}>
You pressed me {count} times
</button>
);
}
Swoją drogą można było zastosować updater function, który już poznaliśmy. A oto hook useCount:
import { useState } from 'react';
function useCount(initialCount = 0) {
const [count, setCount] = useState(initialCount);
const increment = () => {
setCount(count + 1);
};
const decrement = () => {
setCount(count - 1);
};
const reset = () => {
setCount(initialCount);
};
return {
count,
increment,
decrement,
reset,
};
}
export default useCount;
Też brakuje mi updater function. Bo to nie chodzi o to, że decrement czy increment są strzałkowe – tu chodzi o to, że setState może albo działać na state (i state jest zależnością), albo przyjąć callback, którego argument to prevState (jaki by on nie był) a return to instrukcja, co z tym prevState zrobić:
function handleClick() {
setAge(a => a + 1); // setAge(42 => 43)
setAge(a => a + 1); // setAge(43 => 44)
setAge(a => a + 1); // setAge(44 => 45)
}
Ok, następny przykład useState:
import { useState } from 'react';
export default function MyInput() {
const [text, setText] = useState('hello');
function handleChange(e) {
setText(e.target.value);
}
return (
<>
<input value={text} onChange={handleChange} />
<p>You typed: {text}</p>
<button onClick={() => setText('hello')}>
Reset
</button>
</>
);
}
Tu mamy onClick setText z argumentem, żeby to działało – onclick musi być przekazany jako funkcja strzałkowa zwracająca wywołanie funkcji setText.
Warto zwrócić uwagę:
- Zmienne reaktywne state zawsze lądują w tablicy zależności
- Funkcje setState nigdy nie lądują w tablicy zależności
- Aby wywołać setState bez używania state (i produkowania zależności) musimy:
- Skorzystać z updater function, która w callbacku ma prevState i w returnie pokazane, co z nim zrobić
- Wpisać tam jakąś wartość, np. setState(42) nie powoduje żadnych zależności, setState(get42()) tylko funkcji get42, której jeszcze można zrobić useCallback i tam określić zależności
Wartości boolowskie się świetnie nadają na stan:
import { useState } from 'react';
export default function MyCheckbox() {
const [liked, setLiked] = useState(true);
function handleChange(e) {
setLiked(e.target.checked);
}
return (
<>
<label>
<input
type="checkbox"
checked={liked}
onChange={handleChange}
/>
I liked this
</label>
<p>You {liked ? 'liked' : 'did not like'} this.</p>
</>
);
}
Czemu świetnie? Bo zawsze, jak chcemy im toggle zrobić to w setState dajemy updater z prevState => !prevState.
Tutaj taki hook z internetu, useToggle:
import { useState } from "react"
export default function useToggle(defaultValue) {
const [value, setValue] = useState(defaultValue)
function toggleValue(value) {
setValue(currentValue =>
typeof value === "boolean" ? value : !currentValue
)
}
return [value, toggleValue]
}
Więcej Reacta niedługo…