Differences

This shows you the differences between two versions of the page.

Link to this comparison view

se:labs:03 [2018/10/20 10:24]
avner.solomon [Tasks]
se:labs:03 [2025/10/19 20:34] (current)
ilie_cristian.sandu [Tasks]
Line 1: Line 1:
 ====== Lab 03 - Frontend ====== ====== Lab 03 - Frontend ======
  
-=====Vue====+=====React====
  
-Vue (read as view) is a powerful fronted framework ​for creating web-app ​interfaces. ​Vue is split into multiple sub-libraries where the core is focusing on creating view elements while the plugins focus on extra functionality like [[https://​vuex.vuejs.org/​|Vuex]], for state management, [[https://​router.vuejs.org/​|Vue Router]], for managing routes ​(URLsinside an app ([[https://​classicalconditioning.github.io/​vue-router-nav/#/​third|Example]]) and much much more since Vue is primarily created on a component system that allows ​you to extend it with your own components ​or reuse components from the web.+React is a modern Javascript library ​for building user interfaces. 
 +  * React makes it easier to create modern interactive UIs. React adheres to the declarative programming paradigmyou can design views for each state of an application and React will update and render the components when the data changesThis is different than imperative programming ​(Javascript). 
 +  * Component-Based: Components are the building blocks of React, they allow you to split the UI into independent,​ reusable pieces that work in isolation. Data can be passed through ​components ​using “props”.
  
-Though we are trying to give you a crash course in Vue, it is recommended to check the official Vue page and read their articles from their own guide ([[https://vuejs.org/​v2/​guide/​|Vue 2.0 Guide]]). Anyone who aims to be using view in any project should at least read all the chapters from this page (except migration from vue 1.0). All links included in this wiki article are must reads.+{{:se:​labs:​react.png?700|}}
  
-Vue js can be used directly by including ​the following script in the ''<​head>''​ +=====React Virtual DOM==== 
-<code html> + 
-<!-- development ​version, ​includes helpful console warnings ​--> +When new elements are added to the UI, a virtual DOM, which is represented as a tree, is created. Each element is a node on this tree. If the state of any of these elements changes, a new virtual DOM tree is created. This tree is then compared or “diffed” with the previous virtual DOM tree. 
-<script src="​https:​//cdn.jsdelivr.net/npm/vue/​dist/​vue.js"></script>+ 
 +Once this is done, the virtual DOM calculates the best possible method to make these changes to the real DOM. This ensures that there are minimal operations on the real DOM. Hence, reducing the performance cost of updating the real DOM. 
 + 
 +{{:​se:​labs:​react_virtual_dom.jpeg?​700|}} 
 + 
 +The red circles represent the nodes that have changed. These nodes represent the UI elements that have had their state changed. The difference between the previous ​version ​of the virtual DOM tree and the current virtual DOM tree is then calculated. When state or props changeReact calls the component function again (i.e. re-renders that component subtree) to produce a new virtual DOM. The reconciliation algorithm then diffs that new tree against the previous one, and only the minimal set of actual DOM operations is applied (batched) to reflect those differences in the real DOM. 
 + 
 +===== JSX ===== 
 +JSX is a syntax extension for JavaScript (resembling XML/HTML) that gets compiled (e.gby Babel/TypeScript) into React.createElement(...) calls (or equivalent). It doesn’t itself have meaning to the browser — it's a compile-time convenience. 
 + 
 +React embraces the fact that rendering logic is inherently coupled with other UI logic: how events are handled, how the state changes over time, and how the data is prepared for display. 
 + 
 +Instead of artificially separating technologies by putting markup and logic in separate files, React separates concerns with loosely coupled units called “components” that contain both. 
 + 
 +<code javascript> 
 +const element = <​h1>​Hello,​ world!</h1>;
 </​code>​ </​code>​
-or + 
-<code html> +In the example belowwe declare a variable called name and then use it inside JSX by wrapping it in curly braces: 
-<!-- production versionoptimized for size and speed --> + 
-<script src="https://​cdn.jsdelivr.net/​npm/​vue"></​script>+ 
 +<code javascript>​ 
 +const name: string ​= "Andrei"
 +const element = <h1>Hello, {name}</h1>;
 </​code>​ </​code>​
  
-Here is a simple example of a Vue App. + 
-<code html> + 
-<!-- this code goes in body --> +===== Components ===== 
-<div id="​app">​ + 
-  <​!-- example of linking attribute to variable --> +User interfaces can be broken down into smaller building blocks called components. 
-  <p v-bind:​title="​message">​ + 
-    Hover your mouse over me for a few seconds +Components allow you to build self-contained, reusable snippets ​of code. If you think of components as LEGO bricks, you can take these individual bricks and combine them together ​to form larger structures. If you need to update ​piece of the UI, you can update the specific component or brick. 
-    to see my dynamically bound title! +{{:​se:​labs:​react_components.png?​700|}} 
-  </​p>​ + 
-  <!-- example ​of linking attribute ​to variable 2 ':'​ is an alias for v-bind-->​ +This modularity allows your code to be more maintainable as it grows because you can easily add, update, and delete components without touching the rest of our application. The nice thing about React components is that they are just JavaScript. 
-  <p :​title="​message">​ + 
-    Hover your mouse over me for few seconds +React historically supported class components, but modern React encourages use of functional components and hooks. In this lab, we’ll only use functional components. 
-    to see my dynamically bound title! + 
-  </​p>​ +<code javascript
-  <!-- example ​of content --> +export default function StartupEngineering() { 
-  <​p>​{{counter}} clicks</​p>​ +  ​return ​<div>StartupEngineering</div>; 
-  <​!-- example ​of event handling 1--> +}
-  <​button v-on:​click="​counter++">​Click me 1</​button>​ +
-  <​!-- example ​of event handling 2 '​@'​ is an alias for v-on--> +
-  <button @click="​counter++">​Click me 2</​button+
-  <​!-- example of event handling 3--> +
-  <button @click="​incremenentCounter"​>Click me 3</button+
-</​div>​+
 </​code>​ </​code>​
 +
 +===== Nesting Components =====
 +
 +Applications usually include more content than a single component. You can nest React components inside each other like you would do with regular HTML elements.
 +
 +The <​Header>​ component is nested inside the <​HomePage>​ component:
 +
 +
 <code javascript>​ <code javascript>​
-//this goes inside a <scripttag at the end of the <body+function Header() { 
-var app = new Vue({ +  return ​<h1>Startup Engineering</h1>; 
-  el: '#​app',​ +} 
-  ​data: ​+ 
-    ​message:​ 'You loaded this page on ' + new Date().toLocaleString(),​ +function HomePage() ​
-    ​counter: 0 +  ​return ​
-  }+    ​<div> 
-  methods: { +      {/* Nesting the Header component */
-    incremenentCounter:​ function() { +      ​<Header /> 
-      ​this.counter++ +    ​</​div>​ 
-    ​} +  ​); 
-  ​} +}
-})+
 </​code>​ </​code>​
 + 
  
-Though it is indeed possible to code a full app like this it is strongly recommended against. That is where [[https://​vuejs.org/​v2/​guide/​components.html|vue components]] come in place, helping you structure your own project. And even thought they can be directly defined in html too it is recommended to use node.js to build your project from .vue component files.+===== Props =====
  
-[[https://​vuejs.org/​v2/​guide/​single-file-components.html|Single file components]] ​is the core feature that will allow you to structure your code by defining new components ​with new HTML tags.+Similar to a JavaScript function, you can design ​components ​that accept custom arguments (or props) that change the component’s behavior or what is visibly shown when it’s rendered to the screen. Then, you can pass down these props from parent components ​to child components. Props are **read only**.
  
-In order to get you started with Vue components you will need node installed and a vue projectThe de facto tool for generating new vue projects ​is and will always be the latest version of [[https://​cli.vuejs.org/​|vue-cli]] utility ​(another independent part of the vuejs infrastructure).+In your HomePage component, you can pass a custom title prop to the Header component, just like you’d pass HTML attributesHere, titleSE ​is a custom argument ​(prop).
  
-In order to install vue-cli all you need to do is + 
-<​code ​bash+<​code ​javascript
-npm install -g @vue/cli +function HomePage({ titleSE: string }) { 
-# OR +  ​return ( 
-yarn global add @vue/cli+    <​div>​ 
 +      <Header title={titleSE} ​/
 +    </​div>​ 
 +  ); 
 +}
 </​code>​ </​code>​
-This will install the vue command in your OS. 
  
-Once installed all you need to do is run ''​vue ​create ​my-project''​ and follow the interactive menu. After generating the project, the 2 commands ​that you will mostly use withing the project folder will be + 
-<​code ​bash+ 
-npm run serve + 
-# OR +===== Conditional Rendering ==== 
-yarn serve+ 
 +We’ll ​create ​a Greeting component ​that displays either of these components depending on whether a user is logged in: 
 + 
 +<​code ​javascript
 +function Greeting(props:​ any) { 
 +  const isLoggedIn: boolean = props.isLoggedIn;​ 
 +  if (isLoggedIn) { 
 +    return <​h1>​Welcome back!</​h1>;​ 
 +  } 
 +  return <​h1>​Please sign up.</​h1>;​ 
 +}
 </​code>​ </​code>​
-for running a local development server on localhost:​8080 ​to interactively test you projectThis page will automatically show the changes ​in your project+ 
-<​code ​bash+We can also use inline if-else operators. 
-npm run buid + 
-# OR +When sending props from parent ​to child component, we can use **object destructuring** ​Destructuring really shines ​in React apps because it can greatly simplify how you write props. 
-yarn build+ 
 +<​code ​javascript
 +function Header({ title }: { title: string }) { 
 +  ​return <​h1>​{title ? title : "​Default title"​}</​h1>;​ 
 +}
 </​code>​ </​code>​
-for building your project. The output will be placed in ./dist folder by default inside your project 
  
-=====Vue Components==== 
  
-As mentioned before, each component is a standalone file allowing you to work collaboratively on developing the app. 
-Let's take a look at the structure of such file 
  
-<code html> 
-<!-- this is the default HelloWordComponent.vue from teh default vue-cli project under ./​src/​components --> 
  
-<!-- the first part from a .vue file called <​template>​ is defining the html code from your component --> +===== Iterating through lists =====
-<​template>​ +
-  <div class="​hello">​ +
-    <​h1>​{{ msg }}</​h1>​ +
-    <p> +
-      For guide and recipes on how to configure / customize this project,<​br>​ +
-      check out the +
-      <a href="​https://​cli.vuejs.org"​ target="​_blank"​ rel="​noopener">​vue-cli documentation</​a>​. +
-    </​p>​ +
-    <​h3>​Installed CLI Plugins</​h3>​ +
-    <​ul>​ +
-      <​li><​a href="​https://​github.com/​vuejs/​vue-cli/​tree/​dev/​packages/​%40vue/​cli-plugin-babel"​ target="​_blank"​ rel="​noopener">​babel</​a></​li>​ +
-      <​li><​a href="​https://​github.com/​vuejs/​vue-cli/​tree/​dev/​packages/​%40vue/​cli-plugin-eslint"​ target="​_blank"​ rel="​noopener">​eslint</​a></​li>​ +
-      <​li><​a href="​https://​github.com/​vuejs/​vue-cli/​tree/​dev/​packages/​%40vue/​cli-plugin-unit-jest"​ target="​_blank"​ rel="​noopener">​unit-jest</​a></​li>​ +
-    </​ul>​ +
-    <​h3>​Essential Links</​h3>​ +
-    <​ul>​ +
-      <​li><​a href="​https://​vuejs.org"​ target="​_blank"​ rel="​noopener">​Core Docs</​a></​li>​ +
-      <​li><​a href="​https://​forum.vuejs.org"​ target="​_blank"​ rel="​noopener">​Forum</​a></​li>​ +
-      <​li><​a href="​https://​chat.vuejs.org"​ target="​_blank"​ rel="​noopener">​Community Chat</​a></​li>​ +
-      <​li><​a href="​https://​twitter.com/​vuejs"​ target="​_blank"​ rel="​noopener">​Twitter</​a></​li>​ +
-      <​li><​a href="​https://​news.vuejs.org"​ target="​_blank"​ rel="​noopener">​News</​a></​li>​ +
-    </​ul>​ +
-    <​h3>​Ecosystem</​h3>​ +
-    <​ul>​ +
-      <​li><​a href="​https://​router.vuejs.org"​ target="​_blank"​ rel="​noopener">​vue-router</​a></​li>​ +
-      <​li><​a href="​https://​vuex.vuejs.org"​ target="​_blank"​ rel="​noopener">​vuex</​a></​li>​ +
-      <​li><​a href="​https://​github.com/​vuejs/​vue-devtools#​vue-devtools"​ target="​_blank"​ rel="​noopener">​vue-devtools</​a></​li>​ +
-      <​li><​a href="​https://​vue-loader.vuejs.org"​ target="​_blank"​ rel="​noopener">​vue-loader</​a></​li>​ +
-      <​li><​a href="​https://​github.com/​vuejs/​awesome-vue"​ target="​_blank"​ rel="​noopener">​awesome-vue</​a></​li>​ +
-    </​ul>​ +
-  </​div>​ +
-</​template>​+
  
-<!-- the second part from the .vue file is defining the logic/code --> + 
-<script+It’s common to have data that you need to show as a list. You can use array methods to manipulate your data and generate UI elements that are identical in style but hold different pieces of information. 
-export default ​+ 
-  ​name'​HelloWorld'​+ 
-  ​props: { +<code javascript
-    // here we define properties ​of our own components +function HomePage() ​
-    // we will see later how this comes into play +  ​const namesstring[] = ["​POLI"​"​ASE",​ "​UNIBUC"​];​ 
-    ​msgString+ 
 +  ​return ( 
 +    <​div>​ 
 +      <Header title="​Universities"​ /> 
 +      <​ul>​ 
 +        {names.map((namestring) => ( 
 +          <li key={name}>​{name}</​li>​ 
 +        ))} 
 +      </ul> 
 +    ​</div> 
 +  ); 
 +
 +</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>​ 
 + 
 +===== Adding Interactivity with State ===== 
 + 
 + 
 + 
 + 
 +React has a set of functions called hooks. Hooks allow you to add additional logic such as state to your components. You can think of state as any information in your UI that changes over time, usually triggered by user interaction. 
 + 
 +You can use state to store and increment the number of times a user has clicked the like button. In fact, this is what the React hook to manage state is called: useState() 
 + 
 +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. 
 + 
 + 
 +<code javascript>​ 
 +function HomePage() { 
 +  ​// ... 
 +  const [likes, setLikes] = React.useState<​number>​(0);​ 
 + 
 +  function handleClick() { 
 +    ​setLikes((likesnumber) => likes + 1);
   }   }
 +
 +  return (
 +    <div>
 +      {/* ... */}
 +      <button onClick={handleClick}>​Likes ({likes})</​button>​
 +    </​div>​
 +  );
 } }
-</script>+</code> 
 + 
 +==== (Optional) Other Useful React Hooks ==== 
 + 
 +While `useState()` is the most common React hook, React also provides several others that help you manage side effects, access DOM elements, and optimize performance. 
 + 
 +=== useEffect === 
 + 
 +The `useEffect()` hook lets you perform **side effects** in your components, such as fetching data, updating the document title, or setting up timers. ​  
 +By default, it runs after every render, but you can control when it runs by specifying dependencies. 
 + 
 +<code javascript>​ 
 +import React, { useState, useEffect } from "​react";​ 
 + 
 +export default function Timer() { 
 +  const [seconds, setSeconds] = useState<​number>​(0);​ 
 + 
 +  useEffect(() => { 
 +    const interval = setInterval(() => { 
 +      setSeconds((s) => s + 1); 
 +    }, 1000); 
 + 
 +    // Cleanup when component unmounts 
 +    return () => clearInterval(interval);​ 
 +  }, []);
  
-<!-- the last/thrid part is the style --> +  return ​<h1>Seconds passed: {seconds}</h1>;
-<!-- Add "​scoped"​ attribute to limit CSS to this component only --> +
-<style scoped>​ +
-h3 { +
-  margin: 40px 0 0;+
 } }
-ul +</​code>​ 
-  ​list-style-type: none+ 
-  ​padding: 0;+**Tip:** 
 +  * <code javascript>​ useEffect(() => {...}, []) // → runs only once (on mount) </​code> ​ 
 +  ​* <code javascript>​ useEffect(() => {...}, [value]) // → runs whenever `value` changes </​code>​  
 + 
 + 
 +=== useRef === 
 + 
 +The `useRef()` hook gives you a **mutable reference** that persists across renders without causing re-renders. ​  
 +It’s useful for accessing DOM elements or storing values like timers. 
 + 
 +<code javascript>​ 
 +import React, { useRef, useEffect } from "​react"​; 
 + 
 +export default function FocusInput() { 
 +  ​const inputRef = useRef<​HTMLInputElement>​(null);​ 
 + 
 +  useEffect(() => { 
 +    inputRef.current?​.focus();​ 
 +  }, []); 
 + 
 +  return <input ref={inputRef} placeholder="​Type here..."​ />;
 } }
-li +</​code>​ 
-  ​display: inline-block+ 
-  ​margin0 10px;+ 
 +=== useContext === 
 + 
 +The `useContext()` hook allows you to share values (like theme, language, or user info) across the component tree **without prop drilling**. 
 + 
 +<code javascript>​ 
 +import React, { createContext,​ useContext } from "​react";​ 
 + 
 +const ThemeContext = createContext("​light"​);​ 
 + 
 +function ThemeDisplay() ​
 +  ​const theme = useContext(ThemeContext)
 +  ​return <​h1>​Current theme{theme}</​h1>​;
 } }
-+ 
-  ​color: #42b983;+export default function App() 
 +  ​return ( 
 +    <​ThemeContext.Provider value="​dark">​ 
 +      <​ThemeDisplay /> 
 +    </​ThemeContext.Provider>​ 
 +  );
 } }
-</​style>​ 
 </​code>​ </​code>​
-An interesting feature of .vue is the ability to use other languages for each of the 3 parts than the standard. As an example here we use scss instead of css which allows nested tags, mixins, funcions and variables. The vue cli project comes by default with scss support. 
-<code css> 
-<style scoped lang="​scss">​ 
-$color: #42b983; // our variables that are supposed to be globals can be defined in another file and then just included 
-@import '​assets/​scss/​global';​ //multiple global variables defined here 
  
-li { + 
-  /this selects every li */ +=== useMemo and useCallback === 
-  ​display: inline-block+ 
-  ​margin: ​10px+These two hooks are used for **performance optimization**. 
-  ​+ 
-    ​/* this selects every a inside of a li */ +  ​* `useMemo()` caches computed values to avoid re-calculating them. 
-    ​color: $color+  * `useCallback()` caches function references to prevent unnecessary re-renders. 
-  }+ 
 +<code javascript>​ 
 +import React, { useState, useMemo, useCallback } from "​react"​; 
 + 
 +export default function ExpensiveCalculation() { 
 +  ​const [count, setCount] = useState<​number>​(0)
 +  ​const [input, setInput] = useState<​number>​(0);​ 
 + 
 +  const squared = useMemo(() => 
 +    ​console.log("​Calculating..."​);​ 
 +    ​return input * input
 +  }, [input]); 
 + 
 +  const increment = useCallback(() => setCount((c) => c + 1), []); 
 + 
 +  return ( 
 +    <​div>​ 
 +      <input 
 +        type="​number"​ 
 +        value={input} 
 +        onChange={(e) => setInput(Number(e.target.value))} 
 +      /> 
 +      <​p>​Square:​ {squared}</​p>​ 
 +      <button onClick={increment}>​Count ({count})</​button>​ 
 +    </​div>​ 
 +  );
 } }
-</​style>​ 
 </​code>​ </​code>​
  
-Now let's see how this component will be used as part as another component. Here is the default code of the Home.vue component that you will find in src/views folder: 
-<code html> 
-<​template>​ 
-  <div class="​home">​ 
-    <img alt="​Vue logo" src="​../​assets/​logo.png">​ 
-    <!-- here we use our subcomponent and we send it a value via our custom defined property called msg --> 
-    <​HelloWorld msg="​Welcome to Your Vue.js App"/>​ 
-  </​div>​ 
-</​template>​ 
  
-<​script>​ +=== useReducer ===
-// @ is an alias to /src +
-import HelloWorld from '​@/​components/​HelloWorld.vue'​ +
-// here we import the hello world component+
  
-export default ​+The `useReducer()` hook is an alternative to `useState()` for handling **more complex state logic**. ​  
-  name'​home'​// this is the name we define for the current component +It works similarly to Redux reducers. 
-  ​components: ​+ 
-    ​HelloWorld+<code javascript>​ 
 +import React, ​useReducer } from "​react";​ 
 + 
 +function reducer(statenumberaction: string) { 
 +  ​switch (action) ​
 +    ​case "​increment":​ 
 +      return state + 1; 
 +    case "​decrement":​ 
 +      return state - 1; 
 +    default: 
 +      return state;
   }   }
-  // here we expose the hello world component 
 } }
-</script>+ 
 +export default function Counter() { 
 +  const [count, dispatch] = useReducer(reducer,​ 0); 
 + 
 +  return ( 
 +    <​div>​ 
 +      <​p>​Count:​ {count}</​p>​ 
 +      <button onClick={() => dispatch("​increment"​)}>​+</​button>​ 
 +      <button onClick={() => dispatch("​decrement"​)}>​-</​button>​ 
 +    ​</div> 
 +  ); 
 +}
 </​code>​ </​code>​
  
-While developing with you you should always have vuejs developer extension (for chrome/​firefox) that will allow you to easily inspect your components and vuex states. 
  
-{{https://​addons.cdn.mozilla.net/​user-media/​previews/​full/​194/​194260.png}}+=== Summary of Common Hooks ===
  
-=====A simple counter component==== +^ Hook ^ Purpose ^ 
-We are going to try to make a counter ​component ​with initialization and that emits events to it's parent +| `useState` | Manage local component ​state | 
-<code html> +| `useEffect` | Handle side effects (fetching data, timers, etc.) | 
-<​template>​ +| `useRef` | Persist values or access DOM elements | 
-  <​div class="​counter">​ +| `useContext` | Share data across components | 
-    ​{{counter}} +| `useMemo` | Cache expensive calculations | 
-  </​div>​ +| `useCallback` | Cache function definitions | 
-  <​button>​Click me</​button>​ +| `useReducer` | Manage complex state logic |
-</​template>​+
  
-<​script>​ +===== Data Binding ===== 
-export default { + 
-  name: '​Counter',​ +Data Binding is the process ​of connecting the view element or user interfacewith the data which populates it. 
-  props: { + 
-    initial: { +In ReactJScomponents are rendered to the user interface and the component’s logic contains the data to be displayed in the view(UI). The connection between the data to be displayed in the view and the component’s logic is called data binding ​in ReactJS. 
-      //allow via a property ​of type Number to set an initial value + 
-      type: Number+<code javascript>​ 
-      ​default:​ 0 +export ​default ​function HomePage() { 
-    } +  ​const [inputFieldsetInputField] = useState<​string>​(""​);​ 
-  }, + 
-  ​data () +  ​function handleChange(e) { 
-    //in components ​data is a function ​and not a property unlike app level, this is further explained ​in vue guide +    ​setInputField(e.target.value);
-    // data needs to be a function that returns our local variables +
-    ​return { +
-      ​counter:​ this.initial //we intiailize coutner with our initial value default ​to 0 +
-    } +
-  ​}+
-  ​methods:​ { +
-   //methods is property of type object that will contain multiple methods for our use +
-   ​increment ​() { +
-     this.counter++ +
-     this.$emit('​valueChanged',​ this.counter//here we emit to the parent an event called value changed +
-     // now the parent will be able to use v-on:​valueChanged or @valueChanged +
-     // the method mapped to valueChanged will recieve teh current value of the counter +
-   }+
   }   }
 +
 +  return (
 +    <div>
 +      <input value={inputField} onChange={handleChange} />
 +      <​h1>​{inputField}</​h1>​
 +    </​div>​
 +  );
 } }
-</​script>​ 
 </​code>​ </​code>​
  
-There are many other features important in components that you should read on: +===== Passing data from child to parent ​component ​===== 
-  * an in-depth explanation of [[https://​vuejs.org/​v2/​guide/​components-props.html|props]] with validation and other features +
-  * [[https://​vuejs.org/​v2/​guide/​components-slots.html|slots]] (allowing you to access the text inside your component ​<​mycomponent>​some content</​mycomponent>​) +
-  * [[https://​vuejs.org/​v2/​guide/​computed.htm|computer properties]] that allows you to define dynamic ready only data that you can access inside your component +
-  * Watchers that run code when a certain value is changed inside data or computed props+
  
-====List rendering ​with v-for===+In react data flows only one way, from a parent component to a child component, it is also known as one way data binding. While there is no direct way to pass data from the child to the parent component, there are workarounds. The most common one is to pass a handler function from the parent to the child component that accepts an argument which is the data from the child component. This can be better illustrated ​with an example. ​
  
-Quite often you will need to generate a list dynamically with a for (a table, a menu, etc). +<​code ​javascript
-For this we have v-for +const Parent = () ={ 
-<​code ​html+  ​const ​[message, ​setMessage] = React.useState("Hello World"); 
-<!-- here we will go over an array called items --+ 
-<!-- items = [{uid:​1, ​message:"some message"​}{uid:2, message:"some other message"}] +  ​return ( 
-<!-- v-for expects you to bind a key via v-bind:key or just :key --> +    <div
-<!-- this key needs to be unique yo each element and is used by v-for to know when an update is made or a new element appeared-->​ +      <h1>​{message}</​h1
-<ul id="​example-1"​+      <Child onMessageSelect={setMessage} ​/> 
-  <li +    </div
-    v-for="​item in items"​ +  ); 
-    :​key="​item.uid"​ +}; 
-  ​> + 
-    ​{{ item.message }+const Child = ({ chooseMessage }: { chooseMessage:​ (message: string) => void }) => { 
-  ​</li+  ​const msg = "Goodbye"; 
-</ul+  ​return ( 
-<!-- if your array does not contain it's own keys you can use the auto generated index of v-for --+    ​<button onClick={() => onMessageSelect(msg)}>Change Message</button
-<!-- index starts from 0 for the first element and keeps increasing --> +  ); 
-<ul id="​example-2">​ +};
-  <​li +
-    v-for="(item, indexin items"​ +
-    :key="​index"​ +
-  ​> +
-    ​{{ item.message }} +
-  ​</​li>​ +
-</​ul>​ +
-<!-- modifying items in data will result in dynamic changes in the interface --> +
-<!-- v-for can also iterate over objects not just arrays --> +
-<ul id="example-3"> +
-  ​<li +
-    ​v-for="(value, keyin object"​ +
-    :key="​key"​ +
-  ​> +
-    {{ key }} -- {{ value }} +
-  ​</li+
-</ul>+
 </​code>​ </​code>​
  
-====Input binding=== +The initial state of the message variable in the Parent component is set to ‘Hello World’ and it is displayed within the h1 tags in the Parent component as shown. We write a chooseMessage function in the Parent component and pass this function as a prop to the Child component. This function takes an argument message. But data for this message argument is passed from within the Child component as shown. So, on click of the Change Message button, msg ‘Goodbye’ will now be passed to the chooseMessage handler function in the Parent component and the new value of message in the Parent component will now be ‘Goodbye’. This way, data from the child component(data in the variable msg in Child component) is passed to the parent component. 
-In many apps you will have inputs and you will want this inputs ​to be linked ​directly ​to a variable ​in a 2-way connectionWhen the input cahnges the variable updates ​and when the variable changes the input updates. This is done via v-model + 
-<​code ​html+ 
-<​template>​ +===== Tailwind CSS ===== 
-  ​<div> + 
-    <input v-model="message" ​placeholder="edit me"> +Tailwind CSS is a **utility-first CSS framework** that allows ​you to build custom designs quickly and efficiently. ​  
-    <​p>​Message is: {{ message }}</p+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 React components. ​  
-  </​div>​ +This approach gives you more flexibility without writing custom CSS. 
-</​template>​ + 
-<​script>​ +Some key concepts of Tailwind CSS: 
-export default { +  * **Utility-First**: Tailwind provides small, single-purpose classes for styling (for example, `p-4` for padding or `text-center` for text alignment). 
-  ​name: '​HelloWorld',​ +  * **Responsive Design**: Tailwind has built-in support for responsive design, enabling you to style elements differently based on screen size. 
-  data (+  * **Customization**:​ You can customize or extend Tailwind'​s default configuration by adding your own color palettes, spacing, or typography. 
-    return { + 
-      message: 'some initial value'​ + 
-    } +**Centering Text** 
-  }+ 
 +To center-align text and add some padding in React, you can use the `text-center` and `p-4` utilities with `className`:​ 
 + 
 +<​code ​javascript
 +export default function CenteredText() { 
 +  ​return ( 
 +    <div className="text-center p-4"
 +      <h1 className="text-xl font-bold">Hello, Tailwind CSS!</h1
 +    </​div>​ 
 +  );
 } }
-</​script>​ 
 </​code>​ </​code>​
-The above code will instantly update the displayed text as you type. 
-You can use a [[https://​vuejs.org/​v2/​guide/​computed.html#​Watchers|watcher]] over the variable message to detect every update for extra functionality. 
  
-====Component lifecycle===+**Responsive Layout**
  
-In the lifecycle of vue apps each vue component has multiple points where you can hook your own code+With Tailwind, ​you can easily create responsive layouts using its responsive utilities  
-Refer to the following diagram to learn the hooks:+For instance, ​to set different column layouts on different screen sizes, you might do:
  
-{{https://d33wubrfki0l68.cloudfront.net/435786c6cbd23e078c35c2b21f40e1756b2c3d30/2098f/images/vuejs/​external/​component-lifecycle.png?600}}+<code javascript>​ 
 +export default function ResponsiveGrid() ​{ 
 +  return ( 
 +    <div className="​grid grid-cols-1 md:grid-cols-2 lg:​grid-cols-4 gap-4">​ 
 +      <div className="​bg-blue-200 p-4">​Item 1</div> 
 +      <div className="​bg-blue-200 p-4">​Item 2</div> 
 +      <div className="​bg-blue-200 p-4">​Item 3</div> 
 +      <div className="​bg-blue-200 p-4">​Item 4</div> 
 +    </div> 
 +  ); 
 +
 +</code> 
 + 
 +**Button Styling** 
 + 
 +Tailwind allows you to create buttons with custom styles by combining multiple utility classes  
 +In React, use `className` for the styling attribute:
  
-Note that data does not exist in the before event hook so our firs opportunity to play around with stuff is in creates 
 <code javascript>​ <code javascript>​
-export default { +export default ​function StyledButton() ​
-  ​data() { +  ​return ​
-    ​return { +    ​<button className="​bg-blue-500 hover:​bg-blue-700 text-white font-bold py-2 px-4 rounded">​ 
-      ​property: '​Blank'​ +      ​Click Me 
-    ​} +    ​</​button>​ 
-  },+  ​); 
 +} 
 +</​code>​
  
-  computed: { +**More Examples**
-    propertyComputed() { +
-      console.log('​I change when this.property changes.'​) +
-      return this.property +
-    } +
-  },+
  
-  created() { +Tailwind also provides utilities for: 
-    this.property = '​Example property update.' +  * **Text colors** – `text-red-500`,​ `text-gray-700`,​ `text-green-600` 
-    ​console.log('​propertyComputed will update, as this.property ​is now reactive.'+  * **Backgrounds** – `bg-blue-100`,​ `bg-yellow-200` 
-  }+  * **Spacing** – `m-4`, `p-2`, `px-6` 
 +  * **Flexbox and grid layouts** – `flex`, `items-center`,​ `justify-between`,​ `grid-cols-3` 
 +  * **Typography** – `font-bold`,​ `text-lg`, `tracking-wide` 
 + 
 +You can find the full list of utilities and examples in the official Tailwind CSS documentation: ​  
 +**[[https://​tailwindcss.com/​docs|https://​tailwindcss.com/​docs]]** 
 + 
 +===== (OptionalUseful Resources for Modern React Development ===== 
 + 
 +Once you understand the basics of React, there are several modern libraries and frameworks that can help you build professional,​ scalable applications more efficiently  
 +Below are some of the most widely used tools in the React ecosystem
 + 
 +=== ShadCN/UI === 
 + 
 +[[https://​ui.shadcn.com/​|ShadCN/​UI]] ​is a modern React component library built with **Tailwind CSS** and **Radix UI**.   
 +It provides ready-to-use,​ accessible, and themable components (buttons, dialogs, data tables, forms, tooltips, etc.) that you can copy directly into your project and customize. 
 + 
 +  ​* Designed for flexibility — you own the code of each component. 
 +  * Uses Tailwind for styling. 
 +  * Fully compatible with Next.js and Vite setups. 
 + 
 +**Example (Button component):​** 
 + 
 +<code javascript>​ 
 +import { Button ​from "​@/​components/​ui/​button";​ 
 + 
 +export default function Example() { 
 +  return <Button variant="​outline">​Click me</​Button>;​
 } }
 </​code>​ </​code>​
  
 +=== TanStack React Query ===
 +
 +[[https://​tanstack.com/​query/​latest|TanStack Query (React Query)]] is a powerful library for **data fetching, caching, and synchronization** in React apps.
 +
 +It simplifies working with APIs by managing loading states, caching results, refetching automatically,​ and handling background updates — all with minimal code.
 +
 +**Example (fetching data):**
 +
 +<code javascript>​
 +import { useQuery } from "​@tanstack/​react-query";​
 +
 +async function fetchUsers() {
 +  const res = await fetch("​https://​jsonplaceholder.typicode.com/​users"​);​
 +  return res.json();
 +}
 +
 +export default function Users() {
 +  const { data, isLoading, error } = useQuery({
 +    queryKey: ["​users"​],​
 +    queryFn: fetchUsers,
 +  });
 +
 +  if (isLoading) return <​p>​Loading...</​p>;​
 +  if (error) return <​p>​Error loading data</​p>;​
 +
 +  return (
 +    <ul>
 +      {data.map((user) => (
 +        <li key={user.id}>​{user.name}</​li>​
 +      ))}
 +    </ul>
 +  );
 +}
 +</​code>​
 +
 +=== TanStack Table ===
 +
 +[[https://​tanstack.com/​table/​latest|TanStack Table]] (formerly React Table) is a lightweight headless table library for building **interactive and customizable data tables**.  ​
 +You control how the table is rendered — it only provides the logic for sorting, filtering, pagination, and selection.
 +
 +**Example (basic table setup):**
 +
 +<code javascript>​
 +import { useReactTable,​ getCoreRowModel } from "​@tanstack/​react-table";​
 +
 +const data = [
 +  { name: "​Alice",​ age: 25 },
 +  { name: "​Bob",​ age: 30 },
 +];
 +
 +const columns = [
 +  { header: "​Name",​ accessorKey:​ "​name"​ },
 +  { header: "​Age",​ accessorKey:​ "​age"​ },
 +];
 +
 +export default function BasicTable() {
 +  const table = useReactTable({
 +    data,
 +    columns,
 +    getCoreRowModel:​ getCoreRowModel(),​
 +  });
 +
 +  return (
 +    <​table>​
 +      <​thead>​
 +        {table.getHeaderGroups().map((headerGroup) => (
 +          <tr key={headerGroup.id}>​
 +            {headerGroup.headers.map((header) => (
 +              <th key={header.id}>​{header.column.columnDef.header}</​th>​
 +            ))}
 +          </tr>
 +        ))}
 +      </​thead>​
 +      <​tbody>​
 +        {table.getRowModel().rows.map((row) => (
 +          <tr key={row.id}>​
 +            {row.getVisibleCells().map((cell) => (
 +              <td key={cell.id}>​{cell.getValue()}</​td>​
 +            ))}
 +          </tr>
 +        ))}
 +      </​tbody>​
 +    </​table>​
 +  );
 +}
 +</​code>​
 +
 +=== Other Notable Tools ===
 +
 +  * **[[https://​nextjs.org/​|Next.js]]** – React framework for building full-stack apps with server-side rendering and routing.
 +  * **[[https://​react.dev/​learn|React Docs]]** – The official React documentation (excellent for up-to-date examples).
 +  * **[[https://​tailwindcss.com/​docs|Tailwind CSS Docs]]** – Learn how to customize design tokens, responsive utilities, and themes.
 +  * **[[https://​radix-ui.com/​|Radix UI]]** – Low-level, accessible UI primitives used by ShadCN/UI.
 +  * **[[https://​reactrouter.com/​en/​main|React Router]]** – Client-side routing for React apps.
 +  * **[[https://​formik.org/​|Formik]]** and **[[https://​react-hook-form.com/​|React Hook Form]]** – For building and validating forms easily.
 +
 +✅ **Tip:​**  ​
 +These libraries are not required for this lab, but they are very common in real-world React projects and can greatly improve developer productivity and user experience.
 +
 +
 + 
 + 
 ====== Tasks ====== ====== Tasks ======
  
-  - Create a new vue project using vue-cli (if you can't install the component globally for any reason it will install in the node_modules/​.bin folder) or you can download ​the generated project {{:se:labs:todo-list.zip|here}} (and run npm install ​or run install after)+  - Download ​the generated project {{:se:labs:se-lab3-tasks.zip|}} (and run **npm install** and **npm run dev**)
   - Create a to do list app:   - Create a to do list app:
-    ​- Create a component that will represent ​todo-list ​item that should have+  - Implement the List component in **components/​ToDoList.tsx** 
 +    ​- 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
-      - a state variable in data() that represents view mode and edit mode of the item 
-      - an edit button that switches item to edit state and makes the item editable 
-      - an save button that emits the new value to the parent and switches back to the view state 
-      - use v-if toe design the 2 states inside the <​template>​ 
-    - Use the previously defined component in Home.vue to list an array of items you define in Home.vue 
     - 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
-    - Your final solution should look like {{:​se:​labs:​todo-list.zip|this}} (you will need to run install again if you download this solution) 
-  - Modify Home.vue to initialize the array of items from localStorage with localStorage.getItem and update the localStorage with localStorage.setItem on edits (or localStorage.removeItem if it needs to be deleted) 
  
 ====== Feedback ====== ====== Feedback ======
  
-Please take a minute to fill in the **[[https://​goo.gl/forms/VbXevv0IufQzRF1i2 ​| feedback form]]** for this lab. +Please take a minute to fill in the **[[https://​forms.gle/PNZYNNZFrVChLjag8 ​| feedback form]]** for this lab.
se/labs/03.1540020297.txt.gz · Last modified: 2018/10/20 10:24 by avner.solomon
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0