React เป็น JavaScript library ที่ได้รับความนิยมสูงสุดสำหรับสร้าง web applications และเมื่อรวมกับ Vibe Coding คุณสามารถสร้าง production-ready apps ได้ในเวลาเพียงไ ม่กี่ชั่วโมง!
# ตรวจสอบว่ามี Node.js แล้วหรือยัง
node --version
npm --version
# ถ้ายังไม่มี ดาวน์โหลดจาก nodejs.org
# แนะนำ LTS version
1. ES7+ React/Redux/React-Native snippets
2. Prettier - Code formatter
3. ESLint
4. Auto Import
5. Tailwind CSS IntelliSense
# สร้าง React app ด้วย Vite (แนะนำ - เร็วกว่า)
npm create vite@latest my-app -- --template react
# หรือใช้ Create React App
npx create-react-app my-app
# เข้า folder
cd my-app
# ติดตั้ง dependencies
npm install
# รันโปรเจค
npm run dev
Prompt:
สร้าง React Todo App ที่มีฟีเจอร์:
Features:
1. เพิ่ม/แก้ไข/ลบ todo
2. ทำเครื่องหมายเสร็จ
3. Filter: All / Active / Completed
4. Counter แสดงจำนวน
5. Local Storage
6. Dark mode toggle
Design:
- ใช้ Tailwind CSS
- Responsive
- Smooth animations
- Modern UI
Tech Stack:
- React Hooks (useState, useEffect, useContext)
- Tailwind CSS
- React Icons
ให้โค้ดพร้อมคำอธิบาย
โค้ดที่ได้:
// App.jsx
import { useState, useEffect, createContext, useContext } from 'react';
import { FiSun, FiMoon, FiPlus, FiTrash2, FiEdit2, FiCheck } from 'react-icons/fi';
// Dark Mode Context
const DarkModeContext = createContext();
export default function App() {
const [darkMode, setDarkMode] = useState(() => {
const saved = localStorage.getItem('darkMode');
return saved === 'true';
});
useEffect(() => {
localStorage.setItem('darkMode', darkMode);
document.documentElement.classList.toggle('dark', darkMode);
}, [darkMode]);
return (
<DarkModeContext.Provider value={{ darkMode, setDarkMode }}>
<div className="min-h-screen bg-gray-50 dark:bg-gray-900 transition-colors">
<TodoApp />
</div>
</DarkModeContext.Provider>
);
}
function TodoApp() {
const { darkMode, setDarkMode } = useContext(DarkModeContext);
const [todos, setTodos] = useState(() => {
const saved = localStorage.getItem('todos');
return saved ? JSON.parse(saved) : [];
});
const [filter, setFilter] = useState('all');
const [inputValue, setInputValue] = useState('');
const [editingId, setEditingId] = useState(null);
// บันทึกลง localStorage
useEffect(() => {
localStorage.setItem('todos', JSON.stringify(todos));
}, [todos]);
// เพิ่ม todo
const addTodo = () => {
if (!inputValue.trim()) return;
if (editingId) {
// แก้ไข todo
setTodos(todos.map(todo =>
todo.id === editingId
? { ...todo, text: inputValue }
: todo
));
setEditingId(null);
} else {
// เพิ่ม todo ใหม่
const newTodo = {
id: Date.now(),
text: inputValue,
completed: false,
createdAt: new Date().toISOString()
};
setTodos([newTodo, ...todos]);
}
setInputValue('');
};
// Toggle completed
const toggleTodo = (id) => {
setTodos(todos.map(todo =>
todo.id === id
? { ...todo, completed: !todo.completed }
: todo
));
};
// ลบ todo
const deleteTodo = (id) => {
setTodos(todos.filter(todo => todo.id !== id));
};
// เริ่มแก้ไข
const startEdit = (todo) => {
setEditingId(todo.id);
setInputValue(todo.text);
};
// ยกเลิกแก้ไข
const cancelEdit = () => {
setEditingId(null);
setInputValue('');
};
// Filter todos
const filteredTodos = todos.filter(todo => {
if (filter === 'active') return !todo.completed;
if (filter === 'completed') return todo.completed;
return true;
});
// นับจำนวน
const activeCount = todos.filter(t => !t.completed).length;
const completedCount = todos.filter(t => t.completed).length;
return (
<div className="container mx-auto px-4 py-8 max-w-2xl">
{/* Header */}
<div className="flex items-center justify-between mb-8">
<h1 className="text-4xl font-bold text-gray-800 dark:text-white">
✨ My Tasks
</h1>
<button
onClick={() => setDarkMode(!darkMode)}
className="p-2 rounded-lg bg-gray-200 dark:bg-gray-700
hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors"
>
{darkMode ? (
<FiSun className="w-6 h-6 text-yellow-400" />
) : (
<FiMoon className="w-6 h-6 text-gray-700" />
)}
</button>
</div>
{/* Stats */}
<div className="grid grid-cols-3 gap-4 mb-6">
<StatCard
label="Total"
value={todos.length}
color="blue"
/>
<StatCard
label="Active"
value={activeCount}
color="yellow"
/>
<StatCard
label="Completed"
value={completedCount}
color="green"
/>
</div>
{/* Input */}
<div className="mb-6">
<div className="flex gap-2">
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && addTodo()}
placeholder={editingId ? "Edit task..." : "Add a new task..."}
className="flex-1 px-4 py-3 rounded-lg border-2 border-gray-300
dark:border-gray-600 dark:bg-gray-800 dark:text-white
focus:border-blue-500 dark:focus:border-blue-400
outline-none transition-colors"
/>
<button
onClick={addTodo}
className="px-6 py-3 bg-blue-500 hover:bg-blue-600 text-white
rounded-lg font-medium transition-colors flex items-center gap-2"
>
{editingId ? (
<>
<FiCheck /> Update
</>
) : (
<>
<FiPlus /> Add
</>
)}
</button>
{editingId && (
<button
onClick={cancelEdit}
className="px-4 py-3 bg-gray-500 hover:bg-gray-600 text-white
rounded-lg transition-colors"
>
Cancel
</button>
)}
</div>
</div>
{/* Filter */}
<div className="flex gap-2 mb-6">
{['all', 'active', 'completed'].map(f => (
<button
key={f}
onClick={() => setFilter(f)}
className={`px-4 py-2 rounded-lg font-medium capitalize transition-colors ${
filter === f
? 'bg-blue-500 text-white'
: 'bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-300 dark:hover:bg-gray-600'
}`}
>
{f}
</button>
))}
</div>
{/* Todo List */}
<div className="space-y-2">
{filteredTodos.length === 0 ? (
<div className="text-center py-12 text-gray-400 dark:text-gray-500">
<p className="text-xl">No tasks {filter !== 'all' && `(${filter})`}</p>
<p className="text-sm mt-2">Add a task to get started!</p>
</div>
) : (
filteredTodos.map(todo => (
<TodoItem
key={todo.id}
todo={todo}
onToggle={toggleTodo}
onDelete={deleteTodo}
onEdit={startEdit}
/>
))
)}
</div>
</div>
);
}
// Component: StatCard
function StatCard({ label, value, color }) {
const colors = {
blue: 'bg-blue-100 dark:bg-blue-900 text-blue-600 dark:text-blue-300',
yellow: 'bg-yellow-100 dark:bg-yellow-900 text-yellow-600 dark:text-yellow-300',
green: 'bg-green-100 dark:bg-green-900 text-green-600 dark:text-green-300'
};
return (
<div className={`p-4 rounded-lg ${colors[color]}`}>
<div className="text-2xl font-bold">{value}</div>
<div className="text-sm opacity-75">{label}</div>
</div>
);
}
// Component: TodoItem
function TodoItem({ todo, onToggle, onDelete, onEdit }) {
return (
<div
className={`group flex items-center gap-3 p-4 rounded-lg border-2
${todo.completed
? 'bg-gray-100 dark:bg-gray-800 border-gray-300 dark:border-gray-600'
: 'bg-white dark:bg-gray-700 border-gray-200 dark:border-gray-600'
}
hover:shadow-md transition-all`}
>
{/* Checkbox */}
<button
onClick={() => onToggle(todo.id)}
className={`flex-shrink-0 w-6 h-6 rounded border-2 flex items-center
justify-center transition-colors ${
todo.completed
? 'bg-green-500 border-green-500'
: 'border-gray-300 dark:border-gray-500 hover:border-green-500'
}`}
>
{todo.completed && <FiCheck className="text-white" />}
</button>
{/* Text */}
<span
className={`flex-1 ${
todo.completed
? 'line-through text-gray-400 dark:text-gray-500'
: 'text-gray-800 dark:text-white'
}`}
>
{todo.text}
</span>
{/* Actions */}
<div className="flex gap-2 opacity-0 group-hover:opacity-100 transition-opacity">
<button
onClick={() => onEdit(todo)}
className="p-2 text-blue-500 hover:bg-blue-50 dark:hover:bg-blue-900
rounded transition-colors"
>
<FiEdit2 />
</button>
<button
onClick={() => onDelete(todo.id)}
className="p-2 text-red-500 hover:bg-red-50 dark:hover:bg-red-900
rounded transition-colors"
>
<FiTrash2 />
</button>
</div>
</div>
);
}
npm install react-icons
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
// tailwind.config.js
export default {
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx}",
],
darkMode: 'class',
theme: {
extend: {},
},
plugins: [],
}
/* src/index.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
Prompt:
สร้าง React E-commerce Product Page ที่มี:
Features:
1. Product image gallery (thumbnails + main image)
2. Product details (name, price, rating, description)
3. Color และ size selector
4. Quantity picker
5. Add to cart (with animation)
6. Related products section
7. Reviews section
Design:
- ใช้ Tailwind CSS
- Responsive (mobile-first)
- Smooth animations
- Modern, clean UI
State Management:
- ใช้ Context API สำหรับ Cart
- Custom hooks
ให้โค้ดครบพร้อม sample data
Prompt:
สร้าง React Real-time Chat App ด้วย Firebase:
Features:
1. User authentication (Google Sign-in)
2. Real-time messages
3. Online users indicator
4. Typing indicator
5. Image upload
6. Emoji picker
7. Message timestamp
Tech Stack:
- React + Hooks
- Firebase (Auth, Firestore, Storage)
- Tailwind CSS
ให้โค้ดครบพร้อม Firebase setup
# สร้าง Next.js app
npx create-next-app@latest my-nextjs-app
# เลือก options:
# ✅ TypeScript? → Yes
# ✅ ESLint? → Yes
# ✅ Tailwind CSS? → Yes
# ✅ App Router? → Yes
cd my-nextjs-app
npm run dev
Prompt:
สร้าง Blog ด้วย Next.js App Router:
Features:
1. Homepage (list of posts)
2. Post detail page
3. Category filter
4. Search functionality
5. MDX support (markdown with components)
6. Table of contents
7. Reading time
8. Dark mode
Pages:
- app/page.tsx (homepage)
- app/blog/[slug]/page.tsx (post detail)
- app/category/[category]/page.tsx
Tech Stack:
- Next.js 14 (App Router)
- TypeScript
- Tailwind CSS
- next-mdx-remote
- gray-matter
ให้โค้ดครบพร้อม sample posts
Prompt:
สร้าง custom hooks สำหรับ:
1. useFetch - fetch data พร้อม loading/error states
2. useLocalStorage - sync state กับ localStorage
3. useDebounce - debounce value
4. useMediaQuery - responsive breakpoints
5. useOnClickOutside - detect click outside element
ให้โค้ดพร้อมตัวอย่างการใช้งาน
ตัวอย่าง:
// hooks/useFetch.js
import { useState, useEffect } from 'react';
export function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
setLoading(true);
const response = await fetch(url);
if (!response.ok) throw new Error('Failed to fetch');
const json = await response.json();
setData(json);
setError(null);
} catch (err) {
setError(err.message);
setData(null);
} finally {
setLoading(false);
}
};
fetchData();
}, [url]);
return { data, loading, error };
}
// การใช้งาน
function UserProfile({ userId }) {
const { data, loading, error } = useFetch(`/api/users/${userId}`);
if (loading) return <LoadingSpinner />;
if (error) return <ErrorMessage message={error} />;
return <div>{data.name}</div>;
}
Prompt:
สร้าง Tabs component แบบ Compound Pattern:
- Flexible API
- Accessible (keyboard navigation)
- Controlled/Uncontrolled modes
- Smooth animations
ใช้ React Context และ cloneElement
Prompt:
สร้าง DataTable component ที่ใช้ Render Props:
- รองรับ sorting, filtering, pagination
- Customizable columns
- Loading states
- Empty states
ให้ตัวอย่างการใช้งานหลายแบบ
Prompt:
สร้าง Shopping Cart ด้วย Context API และ useReducer:
Actions:
- ADD_ITEM
- REMOVE_ITEM
- UPDATE_QUANTITY
- CLEAR_CART
- APPLY_COUPON
Features:
- Calculate totals
- Apply discounts
- Persist to localStorage
- TypeScript types
ให้โค้ดครบพร้อม hooks สำหรับใช้งาน
Prompt:
สร้าง Global State ด้วย Zustand สำหรับ:
Stores:
1. authStore (user, login, logout)
2. cartStore (items, addItem, removeItem)
3. uiStore (theme, sidebar, modals)
Features:
- Persistence
- DevTools
- TypeScript
- Middleware
ให้ตัวอย่างการใช้งานในหลาย components
// Component-based
function Button({ children, variant = 'primary' }) {
const baseClasses = 'px-4 py-2 rounded-lg font-medium transition-colors';
const variants = {
primary: 'bg-blue-500 hover:bg-blue-600 text-white',
secondary: 'bg-gray-200 hover:bg-gray-300 text-gray-800',
danger: 'bg-red-500 hover:bg-red-600 text-white'
};
return (
<button className={`${baseClasses} ${variants[variant]}`}>
{children}
</button>
);
}
// Button.module.css
.button {
padding: 0.5rem 1rem;
border-radius: 0.5rem;
}
.primary {
background: blue;
color: white;
}
// Button.jsx
import styles from './Button.module.css';
function Button({ variant = 'primary' }) {
return <button className={`${styles.button} ${styles[variant]}`} />;
}
Prompt:
สร้าง Design System ด้วย styled-components:
Components:
- Button (variants, sizes)
- Input, Textarea, Select
- Card, Modal, Dropdown
- Typography (H1-H6, Text)
Features:
- Theming
- Responsive
- TypeScript
- Storybook ready
Prompt:
สร้าง unit tests สำหรับ:
1. TodoList component
- render todos correctly
- add new todo
- toggle todo
- delete todo
2. useFetch hook
- loading state
- success state
- error state
3. Form validation
- required fields
- email validation
- submit handler
ใช้ Jest + React Testing Library
ให้ best practices
// ❌ ไม่ดี - re-render ทุกครั้ง
function ExpensiveComponent({ data }) {
return <div>{/* complex rendering */}</div>;
}
// ✅ ดี - re-render เฉพาะเมื่อ data เปลี่ยน
const ExpensiveComponent = React.memo(function({ data }) {
return <div>{/* complex rendering */}</div>;
});
function ProductList({ products, category }) {
// ✅ Memoize ค่าที่ compute แพง
const filteredProducts = useMemo(() => {
return products.filter(p => p.category === category);
}, [products, category]);
// ✅ Memoize function
const handleSort = useCallback((type) => {
// sorting logic
}, []);
return <div>{/* render */}</div>;
}
// Lazy loading
const AdminPanel = lazy(() => import('./AdminPanel'));
function App() {
return (
<Suspense fallback={<LoadingSpinner />}>
<AdminPanel />
</Suspense>
);
}
React + Vibe Coding เป็นทักษะที่คุ้มค่าที่สุดในตอนนี้:
อยากเป็น React Developer มือโปร? E-book Unlocked Vibe Coding มี:
ติดต่อเรียน React + AI:
อ่านบทความอื่นๆ: