React å¿çšâ ã®ãããã
index.html
ããå§ãŸã
<!DOCTYPE html>
<html>
<head>
<title>React App</title>
</head>
<body>
<div id="root"></div> <!-- ããã«Reactãã³ã³ãã³ããæç» -->
<script src="bundle.js"></script> <!-- ã¢ããªã±ãŒã·ã§ã³ã®ã³ãŒã -->
</body>
</html>
// ã³ã³ããŒãã³ãå®çŸ©ïŒå€§æåã§éå§ïŒ
function UserCard({ name, email, children }) {
return (
<div className="card">
<h3>{name}</h3>
<p>{email}</p>
{children}
</div>
);
}
// 䜿çš
<UserCard name="Kurotsuchi Mayuri" email="m.kurotsuchi@seireitei.co.jp">
<button>ç·šé</button>
</UserCard>
props
= 颿°ã®åŒæ°children
= ã¿ã°ã®äžèº«
import React, { useState } from 'react';
function LikeButton() {
// [çŸåšã®å€, ã»ãã¿ãŒé¢æ°] = useState(åæå€)
const [likes, setLikes] = useState(0);
return (
<div>
<button onClick={() => setLikes((prevLikes) => prevLikes + 1)}>
â¡ {likes}
</button>
</div>
);
}
useState(0)
â åæå€0ã§ãããæ°ãäœæsetLikes(likes + 1)
// 3ã€ã®èŠçŽ ãå¿
é
const [value, setValue] = useState(''); // 1. ç¶æ
return (
<input
value={value} // 2. inputèŠçŽ
onChange={(e) => setValue(e.target.value)} // 3. ãã³ãã©ãŒé¢æ°
/>
);
value
ã¯å¿
ãstate
ç±æ¥onChange
ã§state
ãæŽæ°ã³ã³ããŒãã³ã(props, state) â JSX
Reactã®èŠæ±:
çç±: ã¬ã³ããŒäžãReactã¯åæã«
function handleClick() {
fetch('/api/data'); // äºæž¬å¯èœ
}
useEffect(() => {
fetch('/api/data'); // å®å
šãªã¿ã€ãã³ã°
}, []);
function Component() {
fetch('/api/data'); // åãAPIãäœåãå©ã
document.title = "ãã«"; // ã¿ã€ãã«ããã«ãã«ãã
...
}
import { useEffect } from "react";
function Component() {
function cleanup() { // ã¯ãªãŒã³ã¢ãã颿°ïŒãªãœãŒã¹ã®è§£æŸ
console.log("ã¢ã³ããŠã³ãæã次ã®ãšãã§ã¯ãå®è¡å");
}
function setup() { // ãšãã§ã¯ã颿°ïŒå¯äœçšãå®è¡
console.log("DOMæŽæ°åŸã«å®è¡ããã");
return cleanup;
}
useEffect(setup, [/* äŸåé
å */]);
return <div>...</div>;
}
[]
â ååã®ã¿[userId]
â å€å€æŽæã®ã¿useEffect
å®è¡{show && <Component />} // show â true
state
ãprops
ã®å€æŽæ€ç¥props
ãstate
ãå€åããæ
setState
åŒã³åºãprops
ã倿ŽuseEffect
äŸåé
åã®å€å€æŽ{show && <Component />} // show â false
ããžã¥ã¢ã«è§£èª¬ã¯ãã¡ã
use
ã§å§ãŸãç¹å¥ãªé¢æ°
ã³ã³ããŒãã³ãå ã§Reactã®æ©èœã䜿ãããã®é¢æ°
ãã¹ãŠuse
ã§å§ãŸãç¹å¥ãªé¢æ° â ããã¯
function Counter() {
const [count, setCount] = useState(0); // ç¶æ
管ç
const inputRef = useRef(null); // DOMåç
§
useEffect(() => { // å¯äœçš
document.title = `ã«ãŠã³ã: ${count}`;
}, [count]);
return <div>ã«ãŠã³ã: {count}</div>;
}
function MyComponent() {
const [name, setName] = useState(""); // ãã㯠#1
const [age, setAge] = useState(0); // ãã㯠#2
useEffect(() => { ... }, []); // ãã㯠#3
const [email, setEmail] = useState(""); // ãã㯠#4
// Reactå
éšã§ã¯é
åã®ããã«ç®¡çïŒæŠå¿µçã«ïŒ
// [useState, useState, useEffect, useState]
}
åã¬ã³ããŒæã«åãé åºã§ããã¯ãåŒã°ããããšãReactã¯æåŸ ããŠãã
showAge = true
function Component({ showAge }) {
const [name, setName] = useState("ç«éš"); // #1
if (showAge) {
const [age, setAge] = useState(51); // #2
}
const [email, setEmail] = useState(""); // #3
// React: [useState, useState, useState]
}
React: [name, age, email]
showAge = false
function Component({ showAge }) {
const [name, setName] = useState("ç«éš"); // #1
// age ã®ããã¯ãã¹ããããããïŒ
const [email, setEmail] = useState(""); // #2 â ååã®#3
// React: [useState, useState]
// ãããïŒ #3 ã®ããã¯ã¯ã©ãïŒã
}
React: [name, email]
â é åºãå€ãã£ãïŒ
use
ã§å§ãŸã颿°ããåŒã³åºãfunction Component({ condition }) {
if (condition) {
const [state, setState] = useState(0); // NG!
useEffect(() => {
// ...
}, []);
}
return <div>...</div>;
}
function Component({ condition }) {
const [state, setState] = useState(0); // OK!
useEffect(() => {
if (condition) {
// æ¡ä»¶åå²ã¯ããã¯å
éšã§
}
}, [condition]);
return <div>...</div>;
}
ã³ã³ããŒãã³ãéã§ã®ããžãã¯å ±æ
// 1. ååã¯ãuseãã§å§ããïŒå¿
é ïŒ
function useToggle(initialValue = false) {
// 2. çµã¿èŸŒã¿ããã¯ãæäžäœã§åŒã³åºã
const [value, setValue] = useState(initialValue);
// 3. å¿
èŠãªããžãã¯ãæžã
const toggle = () => setValue(prev => !prev);
// 4. å¿
èŠãªããžãã¯ãæžã
return [value, toggle];
}
function Modal() {
// ã«ã¹ã¿ã ããã¯ãåŒã³åºã
const [isOpen, toggleOpen] = useToggle(false);
return (
<>
<button onClick={toggleOpen}>
{isOpen ? 'éãã' : 'éã'}
</button>
{isOpen && <div>ã¢ãŒãã«å
容</div>}
</>
);
}
// ä»ã®ã³ã³ããŒãã³ãã§ãåãããžãã¯ãåå©çšå¯èœ
function Sidebar() {
const [isVisible, toggleVisible] = useToggle(true);
// ...
}
useState
ãåŒã³åºããŠãã â ããã¯
function useCounter(initialValue = 0) {
const [count, setCount] = useState(initialValue);
const increment = () => setCount(prev => prev + 1);
return [count, increment];
}
ä»ã®ããã¯ãåŒã³åºããŠããªã â ãã ã®é¢æ°
function formatPrice(price) {
return `Â¥${price.toLocaleString()}`;
}
// åºæ¬çãªããã¯
function useToggle(initialValue = false) {
const [value, setValue] = useState(initialValue);
const toggle = () => setValue(prev => !prev);
return [value, toggle];
}
// ä»ã®ã«ã¹ã¿ã ããã¯ã䜿ãã«ã¹ã¿ã ããã¯
function useModal() {
const [isOpen, toggleOpen] = useToggle(false); // ã«ã¹ã¿ã ããã¯åŒã³åºã
const [data, setData] = useState(null); // çµã¿èŸŒã¿ããã¯åŒã³åºã
const openModal = (modalData) => {
setData(modalData);
toggleOpen();
};
return { isOpen, data, openModal, closeModal: toggleOpen };
}
ããã¯ã®äžã§ããã¯ãåŒã¶ = æ®éã®ããš
function useToggle(initialValue) {
const [value, setValue] = useState(initialValue); // ããã¯æ®éã®useStateåŒã³åº
const toggle = () => setValue(prev => !prev);
return [value, toggle];
}
// ReactããèŠããšïŒ
function MyComponent() {
const [isOpen, toggleOpen] = useToggle(false); // useToggleã®äžã®useState
const [isDark, toggleDark] = useToggle(true); // 2ã€ç®ã®useToggleã®äžã®useState
// ReactããèŠããšæ®éã®ããã¯åŒã³åºããšåã
}
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch(`/api/users/${userId}`)
.then(res => res.json())
.then(setUser)
.catch(setError)
.finally(() => setLoading(false));
}, [userId]);
if (loading) return <div>ãŠãŒã¶ãŒãèªã¿èŸŒã¿äž...</div>;
// ...
}
function PostList() {
const [posts, setPosts] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch('/api/posts')
.then(res => res.json())
.then(setPosts)
.catch(setError)
.finally(() => setLoading(false));
}, []);
if (loading) return <div>æçš¿ãèªã¿èŸŒã¿äž...</div>;
// ...
}
useEffect
ã®fetch
ãã¿ãŒã³ãåããã°ä¿®æ£ãæ©èœè¿œå ã§äž¡æ¹å€æŽããå¿ èŠããããŸã
function useApi(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
setLoading(true);
fetch(url)
.then(res => res.json())
.then(setData)
.catch(setError)
.finally(() => setLoading(false));
}, [url]);
return { data, loading, error };
}
function UserProfile({ userId }) {
const { data, loading, error } = useApi(`/api/users/${userId}`);
if (loading) return <div>ãŠãŒã¶ãŒãèªã¿èŸŒã¿äž...</div>;
if (error) return <div>ãšã©ãŒ</div>;
return <div>{data.name}</div>;
}
function PostList() {
const { data, loading, error } = useApi('/api/posts');
if (loading) return <div>æçš¿ãèªã¿èŸŒã¿äž...</div>;
if (error) return <div>ãšã©ãŒ</div>;
return data.map(post => <div>{post.title}</div>);
}
// â è²¬ä»»ãæ··åš - åå©çšãã«ãã
function useBadApi(url) {
// ... fetchããžãã¯
if (loading) return <div>èªã¿èŸŒã¿äž...</div>; // UIãããã¯ã決ããŠã
return data; // ããã¯ãããŒã¿ãŒããè¿ããŠãïŒ
}
// â
ããŒã¿ã ããè¿ããŠã衚瀺ã¯åã³ã³ããŒãã³ãã«ä»»ãã
function useApi(url) {
// ... fetchããžãã¯
return { data, loading, error }; // ã³ã³ããŒãã³ããè¡šç€ºãæ±ºãã
}
ããã¯ã¯ç¶æ ã管çãã³ã³ããŒãã³ããJSXã管ç
// è€æ°ã®ã³ã³ããŒãã³ãã§åãããžãã¯
function Profile() {
const [isOpen, toggleOpen] = useToggle(false);
// ...
}
function Settings() {
const [isVisible, toggleVisible] = useToggle(true);
// ...
}
äžåºŠæžãã°ãã©ãã§ã䜿ãã
function useApi(url) {
// 3ã€ã®ç¶æ
+ useEffect
// è€éãªfetchããžãã¯
// ...
}
function Profile() {
// ã·ã³ãã«ãª1è¡
const { data, loading, error } = useApi(url);
}
å®è£ ã®è©³çŽ°ãæ°ã«ããªããŠãã
ããã¯ã¯ç¬ç«ããŠãã¹ãã§ãã
ããžãã¹ããžã㯠vs 衚瀺ããžãã¯
function Component({ showData }) {
if (showData) {
const [data, setData] = useState(null);
useEffect(() => {
fetchData().then(setData);
}, []);
}
return <>...</>;
}
fetchData
ãå®çŸ©ãããŠããªãuseEffect
ã®äŸåé
åãééãfunction getUser(id) { // A
return fetch(`/users/${id}`);
}
function useUser(id) { // C
const [user, setUser] = useState(null);
return user;
}
function useUser(id) { // B
return fetch(`/users/${id}`);
}
function User(id) { // D
const [user, setUser] = useState(null);
return <div>{user}</div>;
}
getUser(id)
useUser(id)
useUser(id)
User(id)
use
ã§å§ãŸã
function useCounter() {
let count = 0; // æ®éã®å€æ°
const increment = () => count++;
return [count, increment];
}
count
ãuseState
ãããªã â åã¬ã³ããªã³ã°ãããªã
increment
ã®æžãæ¹ãééãuseState
ã§ç®¡çããå¿
èŠããã
仿¥åŠãã å 容ãå®éã«äœ¿ã£ãŠã¿ããïŒ
å
±éã®fetch
ãã¿ãŒã³ãuseApi
ããã¯ã«æœåºããŠãã ãã
PokemonCard
ã§ fetch
TypeInfo
ã§ãåã fetch
useApi(url)
ãäœæfunction useApi<T>(url: string) {
// 1. data, loading, error ã®ç¶æ
ã管ç
// 2. useEffect ã§ fetch åŠçãå®è£
// 3. { data, loading, error } ãè¿ã
}
// 䜿çšäŸ
const { data, loading, error } = useApi<Pokemon>(url);
ããããšãããããŸãã