Kontynuujemy poznawanie Reacta i TypeScripta razem, bo osobno robiliśmy już i jedno i drugie. Trochę proste ćwiczenia, aby się wyrobić. Zaczynajmy.
Ok, w components tworzymy Counter.tsx:
import {useState} from 'react';
const Counter = () => {
const [count, setCount] = useState<number>(0);
return (
<>
</>
)
}
export default Counter;
Tak wygląda każdy komponent. Najpierw importy, potem opcjonalnie propsy (interfejs/typ, też mogą być z importu, ale np. taki JSX.Element będzie wymagał pliku tsx, bez tego – ts obleci). Potem RFC, potem export default.
Ok, to teraz zróbmy wyświetlanie tego komponentu plus increment/decrement używając setState i updater function, znamy to, React 101 to jest:
import {useState} from 'react';
const Counter = () => {
const [count, setCount] = useState<number>(0);
return (
<>
<h1>Count is {count}</h1>
<button onClick={() => setCount((prev) => prev + 1)}>+1</button>
<button onClick={() => setCount((prev) => prev - 1)}>-1</button>
</>
)
}
export default Counter;
Ok, pamiętając o imporcie wrzucamy to w App.tsx:
<Counter/>
No dobra, a teraz lifting state up, prop drilling, czy jak to się tam nazywa. W sumie jedno i drugie, to jest propsy idą w jedynym słusznym kierunku (w dół), z drugiej strony stan można wynieść w górę (do komponentu rodzica).
No to jedziemy, tworzymy Counter2.tsx w components i definiujemy propsy:
type CounterProps = {
setCount: React.Dispatch<React.SetStateAction<number>>,
children: JSX.Element,
}
Nie powinno nas dziwić ani jedno ani drugie, tłumaczyliśmy już to. Teraz sam komponent + export:
const Counter2 = ({ setCount, children }: CounterProps) => {
return (
<>
<h1>{children}</h1>
<button onClick={() => setCount((prev) => prev + 1)}>+1</button>
<button onClick={() => setCount((prev) => prev - 1)}>-1</button>
</>
)
}
export default Counter2;
Teraz import i próbujemy:
return (
<div className="App">
<Counter/>
<Counter2>
</Counter2>
</div>
)
Pokazuje błąd. Nie daliśmy dzieci ani setCounta. Dajmy dziecko:
<Counter2>
<h1>Count is 1</h1>
</Counter2>
Nadal setCount się domaga. Czyli tak, jak ma być. Dajmy mu setCount i niech to dziecko dynamicznie się wyświetla:
import Counter from './components/Counter'
import Counter2 from './components/Counter2';
function App(): JSX.Element {
const [count, setCount] = useState<number>(0);
return (
<div className="App">
<Counter/>
<Counter2 setCount={setCount}>
<h1>Count is {count}</h1>
</Counter2>
</div>
);
}
export default App;
Ok, na dzisiaj wystarczy, więcej TSowego Reacta już niedługo!