6.1 הקדמה לריאקט ו JSX פתרון
פתרון - הקדמה לריאקט ו-JSX¶
פתרון תרגיל 1¶
א-ב. הקמה והרצה:
npm create vite@latest my-first-react -- --template react-ts
cd my-first-react
npm install
npm run dev
ג. קובץ src/App.tsx:
function App() {
return (
<div>
<h1>Amit Pinchasi</h1>
<p>I am a software developer who loves teaching.</p>
</div>
);
}
export default App;
ד. לאחר שמירת הקובץ, השינוי מופיע אוטומטית בדפדפן בלי ריענון ידני - זה HMR (Hot Module Replacement) של Vite.
פתרון תרגיל 2¶
function Profile() {
const firstName = "Alice";
const lastName = "Smith";
const age = 30;
const profession = "Software Developer";
const hobbies = ["reading", "coding", "hiking", "cooking"];
return (
<div>
<h1>{firstName} {lastName}</h1>
<p>Age: {age} (in 10 years: {age + 10})</p>
<p>Profession: {profession}</p>
<p>Number of hobbies: {hobbies.length}</p>
<p>Hobbies: {hobbies.join(", ")}</p>
<p>Current date and time: {new Date().toLocaleString()}</p>
</div>
);
}
פתרון תרגיל 3¶
function StyledCard() {
const isVIP = true;
const fontSize = 18;
const name = "Alice";
const cardStyle = {
backgroundColor: isVIP ? "#ffd700" : "#f0f0f0",
fontSize: `${fontSize}px`,
padding: "20px",
borderRadius: "12px",
border: isVIP ? "2px solid #b8860b" : "1px solid #ccc",
};
return (
<div className="card" style={cardStyle}>
<h2 className="card-title">{name}</h2>
<p className="card-status">{isVIP ? "VIP Member" : "Regular Member"}</p>
</div>
);
}
function App() {
return (
<div>
<StyledCard />
{/* to show the non-VIP version, change isVIP inside the component */}
</div>
);
}
הערה: כרגע אין לנו props אז שני הכרטיסים יראו אותו דבר. בשיעור הבא נלמד להעביר נתונים לקומפוננטה דרך props.
פתרון תרגיל 4¶
function UserInfo() {
const name = "Alice Smith";
const email = "alice@example.com";
const age = 30;
return (
<>
<dt>Name</dt>
<dd>{name}</dd>
<dt>Email</dt>
<dd>{email}</dd>
<dt>Age</dt>
<dd>{age}</dd>
</>
);
}
function App() {
return (
<dl>
<UserInfo />
</dl>
);
}
אם היינו עוטפים ב-<div>, ה-HTML שנוצר היה:
<dl>
<div> <!-- this is invalid! dt/dd must be direct children of dl -->
<dt>Name</dt>
<dd>Alice Smith</dd>
...
</div>
</dl>
Fragment פותר את הבעיה כי הוא לא מוסיף אלמנט ל-DOM.
פתרון תרגיל 5¶
function ProductCard() {
const name = "Wireless Headphones";
const price = 299.99;
const description = "High-quality noise-cancelling wireless headphones.";
const inStock = true;
const discountPercent = 15;
const discountedPrice = price * (1 - discountPercent / 100);
return (
<div style={{ border: "1px solid #ddd", padding: "16px", borderRadius: "8px" }}>
<h2>{name}</h2>
<p>{description}</p>
<p>
Price: ${price.toFixed(2)}
</p>
<p>
Discount: {discountPercent}% off - Final price: ${discountedPrice.toFixed(2)}
</p>
<p style={{ color: inStock ? "green" : "red", fontWeight: "bold" }}>
{inStock ? "In Stock" : "Out of Stock"}
</p>
</div>
);
}
פתרון תרגיל 6¶
function Clock() {
const now = new Date();
const hour = now.getHours();
const dateString = now.toLocaleDateString("he-IL");
const dayOfWeek = now.toLocaleDateString("he-IL", { weekday: "long" });
let timeOfDay: string;
let greeting: string;
if (hour >= 5 && hour < 12) {
timeOfDay = "morning";
greeting = "Good morning!";
} else if (hour >= 12 && hour < 17) {
timeOfDay = "afternoon";
greeting = "Good afternoon!";
} else if (hour >= 17 && hour < 21) {
timeOfDay = "evening";
greeting = "Good evening!";
} else {
timeOfDay = "night";
greeting = "Good night!";
}
return (
<>
<h1>{greeting}</h1>
<p>Date: {dateString}</p>
<p>Day: {dayOfWeek}</p>
<p>Time of day: {timeOfDay}</p>
<p>Current time: {now.toLocaleTimeString()}</p>
</>
);
}
שימו לב שהלוגיקה של if/else נמצאת מחוץ ל-JSX, בחלק ה-JavaScript של הפונקציה. בתוך JSX אפשר להשתמש רק בביטויים.
תשובות לשאלות¶
-
ספרייה נותנת כלים ספציפיים ואנחנו קוראים לה (אנחנו שולטים בזרימה). framework נותן מבנה שלם ומכתיב את הארכיטקטורה (ה-framework שולט בזרימה וקורא לקוד שלנו). ריאקט היא ספרייה - היא מטפלת רק ב-UI ומשאירה לנו את הבחירה בנושאים כמו ניתוב וניהול סטייט.
-
SPA (Single Page Application) היא אפליקציה שטוענת דף HTML אחד ומעדכנת את התוכן דינמית עם JavaScript. היתרונות: חוויית משתמש חלקה בלי טעינה מחדש, ניווט מהיר בין דפים, וביצועים טובים כי רק הנתונים נטענים מהשרת (לא HTML שלם).
-
ריאקט משתמשת באות הראשונה כדי להבדיל בין קומפוננטות לאלמנטי HTML.
<div>- אלמנט HTML.<MyComponent>- קומפוננטה. אם נקרא לקומפוננטה<myComponent>, ריאקט תתייחס אליה כאלמנט HTML לא מוכר. -
classהיא מילה שמורה ב-JavaScript (משמשת להגדרת מחלקות), אז ב-JSX (שהוא JavaScript) משתמשים ב-classNameבמקום. באופן דומה,for(של label) הופך ל-htmlFor. -
צריך Fragments כשרוצים להחזיר כמה אלמנטים בלי להוסיף אלמנט עוטף ל-DOM. נעדיף Fragment על div כשהעטיפה תשבור את מבנה ה-HTML (כמו בדוגמת dl/dt/dd), או כשלא רוצים DOM מיותר שיכול לשבור CSS (למשל Flexbox או Grid).
-
בתוך
{}ב-JSX אפשר לשים כל ביטוי (expression) שמחזיר ערך: משתנים, חישובים, קריאות לפונקציות, ternary, שרשור מחרוזות. אי אפשר לשים statements כמו if, for, while, switch. הפתרון: לחשב את הערך מחוץ ל-JSX ולהשתמש במשתנה, או להשתמש ב-ternary/map בתוך ה-JSX.