Differences

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

Link to this comparison view

se:labs:03 [2018/10/19 10:24]
avner.solomon
se:labs:03 [2023/10/10 01:13] (current)
emilian.radoi [Feedback]
Line 1: Line 1:
-<​solution -hidden>​ +====== Lab 03 - Introduction to React ======
-====== 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 --> +
-<script src="​https://​cdn.jsdelivr.net/​npm/​vue/​dist/​vue.js"></​script>​ +
-</​code>​ +
-or +
-<code html> +
-<!-- production version, optimized for size and speed --> +
-<script src="​https://​cdn.jsdelivr.net/​npm/​vue"></​script>​ +
-</​code>​+
  
-Here is a simple example ​of a Vue App+When new elements are added to the UI, a virtual DOM, which is represented as tree, is created. Each element is a node on this tree. If the state of any of these elements changes, ​new virtual DOM tree is created. This tree is then compared or “diffed” with the previous virtual DOM tree
-<code html> + 
-<​!-- ​this code goes in body --> +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. 
-<div id="​app">​ + 
-  <​!-- example of linking attribute to variable --> +{{:se:labs:​react_virtual_dom.jpeg?​700|}} 
-  <p v-bind:title="​message">​ + 
-    Hover your mouse over me for a few seconds +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. The whole parent subtree then gets re-rendered ​to give the updated UI. This updated tree is then batch updated to the real DOM. 
-    to see my dynamically bound title! + 
-  </​p>​ +===== JSX ===== 
-  <​!-- example of linking attribute to variable 2 ':' ​is an alias for v-bind--> +JSX is an XML-like syntax extension to ECMAScript without any defined semantics.  
-  <​p ​:title="​message">​ + 
-    Hover your mouse over me for a few seconds +React embraces the fact that rendering logic is inherently coupled with other UI logichow events are handled, how the state changes ​over time, and how the data is prepared ​for display. 
-    to see my dynamically bound title! + 
-  </​p>​ +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. 
-  <!-- example ​of content --> + 
-  <​p>​{{counter}} clicks</​p>​ +<code javascript
-  <!-- example of event handling 1--+const element ​= <h1>Hello, world!</h1>;
-  <​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>​
 +
 +In the example below, we declare a variable called name and then use it inside JSX by wrapping it in curly braces:
 +
 +
 <code javascript>​ <code javascript>​
-//this goes inside a <​script>​ tag at the end of the <​body>​ +const name = 'Andrei'; 
-var app new Vue({ +const element = <​h1>​Hello, {name}</​h1>;​
-  el: '#app', +
-  data: { +
-    message: 'You loaded this page on ' + new Date().toLocaleString(), +
-    counter: 0 +
-  }, +
-  methods: ​{ +
-    incremenentCounter:​ function() { +
-      this.counter++ +
-    ​} +
-  } +
-})+
 </​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. 
  
-[[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. 
  
-In order to get you started with Vue components you will need node installed and a vue project. The 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).+===== Components =====
  
-In order to install vue-cli all you need to do is +User interfaces can be broken down into smaller building blocks called components.
-<code bash> +
-npm install -g @vue/cli +
-# OR +
-yarn global add @vue/cli +
-</​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 menuOnce a new folder with the project is generated ​you will need to install ​the node dependencies via ''​npm install'' ​or ''​yarn install''​ +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 structuresIf you need to update a piece of the UI, you can update the specific component ​or brick. 
-</​solution>​ +{{:​se:​labs:​react_components.png?700|}}
-<​solution -hidden>​ +
-=====1Bootstrap and jQuery====+
  
-====1.1Bootstrap====+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 applicationThe nice thing about React components is that they are just JavaScript.
  
-Bootstrap grid [[https://​getbootstrap.com/​docs/​4.0/​examples/​]]+In React, components are functions or classes, we are only going to use functions. Inside your script tag, write a function called header:
  
-For any Bootstrap exercise start with the [[https://​getbootstrap.com/​docs/​4.0/​getting-started/​introduction/​|starter template]] 
  
-Boostrap containers are the basic layout element of bootstrap meant to be used in order to separate content into rows and columns.+<code javascript>​ 
 +export default function StartupEngineering() { 
 +  return <​div>​StartupEngineering</​div>;​ 
 +
 +</​code>​
  
-There are 2 types of contaienrs:​ +===== Nesting Components =====
-  - Standard one //​class ​“container”//​ which has a fixed width depending on the size of the parent element / screen +
-  - Fluid one //​class ​”container-fluid”//​ which will always fill 100% of the parent element in terms of width.+
  
-Inside the container in order to create a grid you separate your content ​in rows which are marked by div elements with //class = “row”//Bootstrap divides each row in 12 units, and columns ​can span over 1 or more of these units.+Applications usually include more content ​than a single componentYou can nest React components inside each other like you would do with regular HTML elements.
  
-Inside each row you place //div// items with //class = “col-[screen-size]-[column-size]”//​. +The <​Header>​ component ​is nested inside ​the <​HomePage>​ component:
-The //screen size// ​is a combination of 2 letters, which dictates on which screen size the columns go, from side by side to stacked version: +
-  - //​col-xs-[size]//​ (or just //​col-size//​):​ will make the columns side by side on any device +
-  - //sm// will switch from stacked to side by side at 576px +
-  - //md// will switch from stacked to side by side at 768px +
-  - //lg// will switch from stacked to side by side at 960px +
-  - //xl// will switch from stacked to side by side at 1200px+
  
-The //column size// is a number from 1 to 12, which represent over how many spaces out of 12 a collumn will span when side by side. For example, you can use two //​col-md-6//​ side by side or one //col-3// and one //col-9//. 
-The column size number can be omitted in case you want to divide a container in equal columns. 
  
-Now, create a container with 4 equal columns with content in them based on the following ​code:+<code javascript>​ 
 +function Header() { 
 +  return <​h1>​Startup Engineering</​h1>;​ 
 +}
  
-<​code>​ +function HomePage() { 
-<div class="​container">​ +  ​return ( 
-  ​<div class="​row">​ +    <​div>​ 
-    <​div ​class="​col"​+      ​{/* Nesting the Header component */} 
-      ​1 of 2 +      <Header ​/>
-    </div> +
-    <div class="​col">​ +
-      2 of 2 +
-    </div> +
-  </​div>​ +
-  <div class="​row">​ +
-    <div class="​col">​ +
-      ​1 of 3 +
-    ​</div> +
-    <div class="​col">​ +
-      2 of 3 +
-    </​div>​ +
-    <div class="​col">​ +
-      3 of 3+
     </​div>​     </​div>​
-  ​</​div>​ +  ​); 
-</​div>​+}
 </​code>​ </​code>​
 + 
  
 +===== Props =====
  
-====1.2. Components (alertslists, navbars)====+Similar to a JavaScript functionyou can design components that accept custom arguments (or propsthat 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**.
  
-[[https://​getbootstrap.com/docs/4.0/​components/​]]+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).
  
-Bootstras comes packed with pre-made components to use in your designs when you need to do a quick design for an MVP (Minimal Viable Product): alerts, buttons, popovers, tooltips , navbars, paginations etc. 
-Go through the example from navbar with toggler: 
-[[https://​getbootstrap.com/​docs/​4.0/​components/​navbar/?#​toggler]] 
  
-Add to the previously created page one menu, 2 alerts in one column and a list group in another column.+<code javascript>​ 
 +function HomePage({titleSE}) { 
 +  return ( 
 +    <​div>​ 
 +      <Header title={titleSE} /> 
 +    </​div>​ 
 +  ); 
 +
 +</​code>​
  
-====1.3. Javascript and jQuery==== 
  
-Bootstrap comes packed with jQuery which allows you to select, modify and create new DOM elements. The selection is done through simple //css// style query. You have here the [[http://​api.jquery.com/​ | full documentation of jQuery]] 
  
-Try making one of the alerts disappear at the press of a button. 
  
-<​code>​ +===== Conditional Rendering ==== 
-$(css selector of button).click(function(){ + 
- $(selector of alert).hide() +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) { 
 +  const isLoggedIn = props.isLoggedIn;​ 
 +  if (isLoggedIn
 +    return <​h1>​Welcome back!</​h1>;​ 
 +  } 
 +  return <​h1>​Please sign up.</​h1>;​ 
 +}
 </​code>​ </​code>​
  
-Using the //.clone// and //.append// methods from the //jQuery docs// clone an element of the list and add it to the end of the list+We can also use inline if-else operators.
  
-Change the content of the element afterwards.+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.
  
-====1.4. Generating list based on AJAX call====+<code javascript>​ 
 +function Header({ title }) { 
 +  return <​h1>​{title ? title : '​Default title'​}</​h1>;​ 
 +
 +</​code>​
  
-//$.ajax//, //$.get// and //$.post// can be used to do AJAX calls between the browser and different servers. For the following exercise you only need to use GET.  GET allows you to fetch data from a given url. 
  
-Create 2 input boxes and a button. At the click of the button fetch 10 jokes from [[http://​www.icndb.com/​api/​|ICNDb]] and use the values from the 2 input boxes in order to replace Chuck Norris’s name in the jokes. You can fetch the value of an input with jQuery by using the //.val()// method. 
  
  
-=====2. Vue.js client side=====+===== Iterating through lists =====
  
-Hello World in Vue: 
  
-Add to the head:+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.
  
-<​code>​ 
-<script src="​https://​unpkg.com/​vue"></​script>​ 
-</​code>​ 
  
-Add to the body: +<​code ​javascript
-<​code>​ +function HomePage() { 
-<​div ​id="app">​ +  const names = ['​POLI',​ '​ASE',​ '​UNIBUC'​];​ 
-  {{ message ​}} + 
-</div+  return ( 
-var app = new Vue({ +    ​<div
-  el: '#​app',​ +      <Header title="Universities" ​/
-  data: { +      <​ul>​ 
-    ​message: 'Hello Vue!' +        ​{names.map((name) => ( 
-  ​} +          <li key={name}>{name}</li
-})+        ))} 
 +      </​ul>​ 
 +    ​</​div>​ 
 +  ​); 
 +}
 </​code>​ </​code>​
-Binding value to attribute instead of content: 
  
-<​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.
-<div id="​app-2">​ +
-  <span v-bind:​title="​message">​ +
-    Hover your mouse over me for a few seconds +
-    ​to see my dynamically bound title! +
-  </​span>​ +
-</​div>​+
  
-Conditionals:​ +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>​ + 
-<div id="​app-3"​+<​code ​javascript
-  <span v-if="​seen">​Now you see me</span+const universitiesItems = universities.map((uni) ​=> 
-</div>+  <li key={uni.id}
 +    ​{uni.name} 
 +  ​</li> 
 +);
 </​code>​ </​code>​
  
-Print list directly from an array: +===== Adding Interactivity with State ===== 
-<​code>​ + 
-<div id="​app-4">​ + 
-  <​ol>​ + 
-    <​li v-for="​todo ​in todos">​ + 
-      {{ todo.text }} +React has 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. 
-    </​li>​ + 
-  </​ol>​ +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() 
-</div> + 
-<script type=”text/​javascript+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. 
-var app4 = new Vue({ +The only argument to useState() is the initial state
-  ​el: '#​app-4',​ + 
-  ​data: { + 
-    todos: ​[ +<code javascript>​ 
-      { text: 'Learn JavaScript'​ }+function HomePage(
-      { text: 'Learn Vue' }, +  ​// ... 
-      text: 'Build something awesome'​ } +  ​const [likessetLikes] = React.useState(0);​ 
-    ​]+ 
 +  ​function handleClick() ​
 +    ​setLikes(likes => likes + 1);
   }   }
-}) + 
-</script>+  return ( 
 +    <​div>​ 
 +      {/* ... */} 
 +      <button onClick={handleClick}>​Likes ({likes})</​button>​ 
 +    </div> 
 +  ); 
 +}
 </​code>​ </​code>​
  
-Dynamic methods (bind an event to a method that will alter the data):+===== Data Binding =====
  
-<​code>​ +Data Binding is the process of connecting the view element or user interface, with the data which populates it. 
-<div id="​app-5">​ + 
-  <​p>​{{ message }}</​p>​ +In ReactJS, components 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. 
-  <​button v-on:​click="​reverseMessage">​Reverse Message</​button>​ + 
-</div+<code javascript
-var app5 = new Vue({ +export default function HomePage(
-  ​el: '#​app-5'​, +  ​const [inputFieldsetInputField] = useState(''​); 
-  data: { + 
-    message: ​'Hello Vue.js!+  function ​handleChange(e) { 
-  }, +      ​setInputField(e.target.value);
-  ​methods: { +
-    reverseMessage: ​function () { +
-      ​this.message = this.message.split(''​).reverse().join(''​) +
-    }+
   }   }
-})+ 
 +  return ( 
 +      <​div>​ 
 +          <input value={inputFieldonChange={handleChange}/>​ 
 +          <​h1>​{inputField}</​h1>​ 
 +      </​div>​ 
 +  ​)
 +}
 </​code>​ </​code>​
  
-Binding inputs to data+===== Passing ​data from child to parent component ===== 
  
-<​code>​ +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 componentthere 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. ​
-<div id="​app-6">​ +
-  <p>{{ message }}</​p>​ +
-  <input v-model="​message">​ +
-</​div>​ +
-var app6 = new Vue({ +
-  el: '#​app-6'​, +
-  ​data: { +
-    message: 'Hello Vue!'​ +
-  } +
-})+
  
 +<code javascript>​
 +const Parent = () => {
 +  const [message, setMessage] = React.useState("​Hello World"​);​
 +  const chooseMessage = (message) => {
 +    setMessage(message);​
 +  };
 +  return (
 +    <div>
 +      <​h1>​{message}</​h1>​
 +      <Child chooseMessage={chooseMessage} />
 +    </​div>​
 +  );
 +};
 +const Child = ({ chooseMessage }) => {
 +  let msg = '​Goodbye';​
 +  return (
 +    <div>
 +      <button onClick={() => chooseMessage(msg)}>​Change ​   Message</​button>​
 +    </​div>​
 +  );
 +};
 </​code>​ </​code>​
  
-You can also define your own components ​as shown [[https://​vuejs.org/​v2/​guide/#​Composing-with-Components | here]]+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.
  
-For the sake of simplicity we will use the //vuetify package// that allows us to use pre-made and pre-style components. Copy the quick [[https://​vuetifyjs.com/​vuetify/​quick-start | starter]] in a blank //html// file in order to start working fast. 
  
-You can also use [[https://​github.com/​pagekit/​vue-resource]] in order to generate AJAX requests easily. 
  
-====== ​Feedback ​======+  
 +  
 +  
 +====== ​Tasks ======
  
-Please take minute ​to fill in the **[[https://goo.gl/forms/​VbXevv0IufQzRF1i2 | feedback form]]** for this lab.+  - Download the generated project {{:​se:​labs:​se-lab3-tasks.zip|}} (amd run npm install and npm run dev) 
 +  - Create ​a to do list app: 
 +  - Implement the List component in component/List.js 
 +    - Create a new component in componentsthat will represent a todo-list item that should have 
 +      - text showing the description of the todo-list 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 
 + 
 +====== Feedback ======
  
-</solution>​+Please take a minute to fill in the **[[https://​forms.gle/​PNZYNNZFrVChLjag8 | feedback form]]** for this lab.
se/labs/03.1539933873.txt.gz · Last modified: 2018/10/19 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