This shows you the differences between two versions of the page.
se:labs:03 [2022/10/25 15:22] gabriel.nicolae3103 [Conditional Rendering] |
se:labs:03 [2024/11/01 19:07] (current) cosmin.dumitrache [Lab 03 - Introduction to React] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Lab 03 - Introduction to React ====== | + | ====== Lab 03 - Frontend ====== |
=====React==== | =====React==== | ||
Line 34: | Line 34: | ||
<code javascript> | <code javascript> | ||
- | const name = 'Andrei'; | + | const name: string = "Andrei"; |
const element = <h1>Hello, {name}</h1>; | const element = <h1>Hello, {name}</h1>; | ||
</code> | </code> | ||
Line 89: | Line 89: | ||
<code javascript> | <code javascript> | ||
- | function HomePage({titleSE}) { | + | function HomePage({ titleSE: string }) { |
return ( | return ( | ||
<div> | <div> | ||
Line 106: | Line 106: | ||
<code javascript> | <code javascript> | ||
- | function Greeting(props) { | + | function Greeting(props: any) { |
- | const isLoggedIn = props.isLoggedIn; | + | const isLoggedIn: boolean = props.isLoggedIn; |
if (isLoggedIn) { | if (isLoggedIn) { | ||
return <h1>Welcome back!</h1>; | return <h1>Welcome back!</h1>; | ||
Line 120: | Line 120: | ||
<code javascript> | <code javascript> | ||
- | function Header({ title }) { | + | function Header({ title }: { title: string }) { |
- | return <h1>{title ? title : 'Default title'}</h1>; | + | return <h1>{title ? title : "Default title"}</h1>; |
} | } | ||
</code> | </code> | ||
Line 136: | Line 136: | ||
<code javascript> | <code javascript> | ||
function HomePage() { | function HomePage() { | ||
- | const names = ['POLI', 'ASE', 'UNIBUC']; | + | const names: string[] = ["POLI", "ASE", "UNIBUC"]; |
return ( | return ( | ||
Line 142: | Line 142: | ||
<Header title="Universities" /> | <Header title="Universities" /> | ||
<ul> | <ul> | ||
- | {names.map((name) => ( | + | {names.map((name: string) => ( |
<li key={name}>{name}</li> | <li key={name}>{name}</li> | ||
))} | ))} | ||
Line 149: | Line 149: | ||
); | ); | ||
} | } | ||
+ | </code> | ||
+ | |||
+ | Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity. | ||
+ | |||
+ | The best way to pick a key is to use a string that uniquely identifies a list item among its siblings. Most often you would use IDs from your data as keys. | ||
+ | |||
+ | <code javascript> | ||
+ | const universitiesItems = universities.map((uni) => ( | ||
+ | <li key={uni.id}>{uni.name}</li> | ||
+ | )); | ||
</code> | </code> | ||
Line 161: | Line 171: | ||
useState() returns an array. The first item in the array is the state value, which you can name anything. It’s recommended to name it something descriptive. The second item in the array is a function to update the value. You can name the update function anything, but it's common to prefix it with set followed by the name of the state variable you’re updating. | useState() returns an array. The first item in the array is the state value, which you can name anything. It’s recommended to name it something descriptive. The second item in the array is a function to update the value. You can name the update function anything, but it's common to prefix it with set followed by the name of the state variable you’re updating. | ||
+ | The only argument to useState() is the initial state. | ||
Line 166: | Line 177: | ||
function HomePage() { | function HomePage() { | ||
// ... | // ... | ||
- | const [likes, setLikes] = React.useState(0); | + | const [likes, setLikes] = React.useState<number>(0); |
function handleClick() { | function handleClick() { | ||
- | setLikes(likes + 1); | + | setLikes((likes: number) => likes + 1); |
} | } | ||
Line 189: | Line 200: | ||
<code javascript> | <code javascript> | ||
export default function HomePage() { | export default function HomePage() { | ||
- | const [inputField, setInputField] = useState(''); | + | const [inputField, setInputField] = useState<string>(""); |
function handleChange(e) { | function handleChange(e) { | ||
- | setInputField(e.target.value); | + | setInputField(e.target.value); |
} | } | ||
return ( | return ( | ||
- | <div> | + | <div> |
- | <input value={inputField} onChange={handleChange}/> | + | <input value={inputField} onChange={handleChange} /> |
- | <h1>{inputField}</h1> | + | <h1>{inputField}</h1> |
- | </div> | + | </div> |
); | ); | ||
} | } | ||
Line 210: | Line 221: | ||
<code javascript> | <code javascript> | ||
const Parent = () => { | const Parent = () => { | ||
- | const [message, setMessage] = React.useState("Hello World"); | + | const [message, setMessage] = React.useState<string>("Hello World"); |
- | const chooseMessage = (message) => { | + | const chooseMessage = (message: string) => { |
setMessage(message); | setMessage(message); | ||
}; | }; | ||
Line 221: | Line 232: | ||
); | ); | ||
}; | }; | ||
- | const Child = ({ chooseMessage }) => { | + | const Child = ({ chooseMessage }: { chooseMessage: string }) => { |
- | let msg = 'Goodbye'; | + | let msg: string = "Goodbye"; |
return ( | return ( | ||
<div> | <div> | ||
- | <button onClick={() => chooseMessage(msg)}>Change Message</button> | + | <button onClick={() => chooseMessage(msg)}>Change Message</button> |
</div> | </div> | ||
); | ); | ||
Line 234: | Line 245: | ||
+ | ===== Tailwind CSS ===== | ||
+ | |||
+ | Tailwind CSS is a utility-first CSS framework that allows you to build custom designs quickly and efficiently. Unlike traditional CSS frameworks, which come with predefined components, Tailwind provides low-level utility classes for controlling layout, color, spacing, typography, and more, directly in your HTML. This approach gives you more flexibility without writing custom CSS. | ||
+ | |||
+ | Some key concepts of Tailwind CSS: | ||
+ | * **Utility-First**: Tailwind provides small, single-purpose classes for styling (e.g., `**p-4**` for padding, `**text-center**` for text alignment). | ||
+ | * **Responsive Design**: Tailwind has built-in support for responsive design, enabling you to style elements differently based on screen size. | ||
+ | * **Customization**: You can customize or extend Tailwind's default configuration, adding your own color palettes, spacing, and more. | ||
+ | Examples: | ||
+ | |||
+ | **Centering Text** | ||
+ | |||
+ | To center-align text and add some padding, you can use the `**text-center**` and `**p-4**` utilities: | ||
+ | |||
+ | <code html> | ||
+ | <div class="text-center p-4"> | ||
+ | <h1 class="text-xl font-bold">Hello, Tailwind CSS!</h1> | ||
+ | </div> | ||
+ | </code> | ||
+ | |||
+ | **Responsive Layout** | ||
+ | |||
+ | With Tailwind, you can easily create responsive layouts using its responsive utilities. For instance, to set different column layouts on different screen sizes, you might do: | ||
+ | |||
+ | <code html> | ||
+ | <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4"> | ||
+ | <div class="bg-blue-200 p-4">Item 1</div> | ||
+ | <div class="bg-blue-200 p-4">Item 2</div> | ||
+ | <div class="bg-blue-200 p-4">Item 3</div> | ||
+ | <div class="bg-blue-200 p-4">Item 4</div> | ||
+ | </div> | ||
+ | </code> | ||
+ | |||
+ | **Button Styling** | ||
+ | |||
+ | Tailwind allows you to create buttons with custom styles by combining utility classes: | ||
+ | |||
+ | <code html> | ||
+ | <button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"> | ||
+ | Click Me | ||
+ | </button> | ||
+ | </code> | ||
- | |||
====== Tasks ====== | ====== Tasks ====== | ||
- | - Download the generated project {{:se:labs:se-lab3-tasks.zip|}} (amd run npm install and npm run dev) | + | - Download the generated project {{:se:labs:se-lab3-tasks.zip|}} (and run `npm install` and `npm start`) |
- Create a to do list app: | - Create a to do list app: | ||
- | - Implement the List component in component/List.js | + | - Implement the List component in `components/ToDoList.tsx` |
- | - Create a new component in components/ that will represent a todo-list item that should have | + | - Create a new component in `components/` that will represent __a todo-list item__ that should have: |
- text showing the description of the todo-list item | - text showing the description of the todo-list item | ||
+ | - edit button that enable you to edit todo-item text | ||
+ | - checkbox that enable you to check todo-item text | ||
+ | - cancel button that enable you to **cancel** a edit action | ||
- delete button that emits an event to parent to remove the item | - delete button that emits an event to parent to remove the item | ||
- Create an input that you will use to create new list items by appending to your array | - Create an input that you will use to create new list items by appending to your array | ||
Line 250: | Line 305: | ||
====== Feedback ====== | ====== Feedback ====== | ||
- | Please take a minute to fill in the **[[https://forms.gle/NuXCJktudGzf4rLg6 | feedback form]]** for this lab. | + | Please take a minute to fill in the **[[https://forms.gle/PNZYNNZFrVChLjag8 | feedback form]]** for this lab. |