Differences

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

Link to this comparison view

se:labs:03 [2018/10/19 11:35]
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 versionincludes 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>​ + 
-</​code>​ +Once this is donethe virtual DOM calculates the best possible method to make these changes to the real DOMThis ensures that there are minimal operations on the real DOMHence, reducing the performance cost of updating the real DOM
-or + 
-<code html> +{{:​se:​labs:​react_virtual_dom.jpeg?​700|}} 
-<!-- production ​version, optimized for size and speed --> + 
-<script src="https://cdn.jsdelivr.net/​npm/​vue"​></script>+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. 
 + 
 +===== JSX ===== 
 +JSX is an XML-like syntax extension to ECMAScript without any defined semantics.  
 + 
 +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. 
 + 
 +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>​
  
-Here is a simple ​example ​of Vue App. +In the example ​below, we declare ​variable called name and then use it inside JSX by wrapping it in curly braces
-<code html> + 
-<!-- this code goes in body --> + 
-<div id="​app">​ +<code javascript
-  <!-- example of linking attribute to variable --> +const name = 'Andrei'; 
-  <p v-bind:title="​message">​ +const element ​= <h1>Hello, ​{name}</h1>;
-    Hover your mouse over me for a few seconds +
-    to see my dynamically bound title! +
-  </p+
-  <​!-- example of linking attribute to variable 2 ':' ​is an alias for v-bind-->​ +
-  <p :title="​message">​ +
-    Hover your mouse over me for a few seconds +
-    to see my dynamically bound title! +
-  ​</p> +
-  <!-- example of content --> +
-  <p>{{counter}} clicks</​p>​ +
-  <!-- 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>​
 +
 +
 +
 +===== Components =====
 +
 +User interfaces can be broken down into smaller building blocks called components.
 +
 +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 a piece of the UI, you can update the specific component or brick.
 +{{:​se:​labs:​react_components.png?​700|}}
 +
 +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.
 +
 +In React, components are functions or classes, we are only going to use functions. Inside your script tag, write a function called header:
 +
 +
 <code javascript>​ <code javascript>​
-//this goes inside a <​script>​ tag at the end of the <​body>​ +export default ​function ​StartupEngineering() { 
-var app = new Vue({ +  ​return <​div>​StartupEngineering</​div>;​ 
-  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.+===== Nesting Components =====
  
-[[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.+Applications usually include more content than a single ​componentYou can nest React components ​inside each other like you would do with regular ​HTML elements.
  
-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).+The <​Header>​ component ​is nested inside ​the <​HomePage>​ component:
  
-In order to install vue-cli all you need to do is 
-<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 menu. After generating ​the project, the 2 commands that you will mostly use withing the project folder will be +<code javascript>​ 
-<code bash+function Header() { 
-npm run serve +  return <​h1>​Startup Engineering</​h1>;​ 
-# OR +
-yarn serve+ 
 +function HomePage() { 
 +  return ( 
 +    <​div>​ 
 +      {/* Nesting ​the Header component */} 
 +      <Header /
 +    </​div>​ 
 +  ); 
 +}
 </​code>​ </​code>​
-for running ​local development server on localhost:​8080 ​to interactively test you projectThis page will automatically show the changes in your project+  
-<​code ​bash+ 
-npm run buid +===== Props ===== 
-# OR + 
-yarn build+Similar to 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 componentsProps are **read only**. 
 + 
 +In your HomePage component, you can pass a custom title prop to the Header component, just like you’d pass HTML attributes. Here, titleSE is a custom argument (prop). 
 + 
 + 
 +<​code ​javascript
 +function HomePage({titleSE}) { 
 +  return ( 
 +    <​div>​ 
 +      <Header title={titleSE} /> 
 +    </​div>​ 
 +  ); 
 +}
 </​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 --> +===== Conditional Rendering ​====
-<​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 --> +We’ll create a Greeting component that displays either of these components depending on whether a user is logged in: 
-<script+ 
-export default ​+<code javascript
-  ​name: '​HelloWorld',​ +function Greeting(props) ​
-  ​props: ​+  ​const isLoggedIn = props.isLoggedIn;​ 
-    ​msg: String+  ​if (isLoggedIn) ​
 +    ​return <​h1>​Welcome back!</​h1>;​
   }   }
 +  return <​h1>​Please sign up.</​h1>;​
 } }
-</script>+</code>
  
-<!-- the last/thrid part is the style --> +We can also use inline if-else operators. 
-<!-- Add "​scoped"​ attribute ​to limit CSS to this component ​only --> + 
-<style scoped+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. 
-h3 + 
-  ​margin40px 0 0;+<code javascript
 +function Header({ title }) 
 +  ​return <​h1>​{title ? title '​Default title'​}</​h1>​;
 } }
-ul { +</​code>​ 
-  list-style-type: none; + 
-  ​padding:​ 0; + 
-} + 
-li + 
-  ​display: inline-block+===== Iterating through lists ===== 
-  ​margin: 0 10px; + 
-} + 
-+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. 
-  ​color: #42b983;+ 
 + 
 +<code javascript>​ 
 +function HomePage() ​
 +  ​const names = ['​POLI',​ '​ASE',​ '​UNIBUC'​]; 
 + 
 +  ​return ( 
 +    <​div>​ 
 +      <​Header title="​Universities"​ /> 
 +      <​ul>​ 
 +        ​{names.map((name) => ( 
 +          <li key={name}>​{name}</​li>​ 
 +        ))} 
 +      </​ul>​ 
 +    </​div>​ 
 +  ​);
 } }
-</​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 { +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. 
-  /* this selects every li *+ 
-  ​displayinline-block;​ +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. 
-  ​margin: ​10px+ 
-  ​+<code javascript>​ 
-    ​/* this selects every a inside of a li */ +const universitiesItems = universities.map((uni) => 
-    color: $color;+  <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 calleduseState() 
 + 
 +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(0); 
 + 
 +  ​function handleClick() ​
 +    ​setLikes(likes => likes + 1);
   }   }
 +
 +  return (
 +    <div>
 +      {/* ... */}
 +      <button onClick={handleClick}>​Likes ({likes})</​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: +===== Data Binding =====
-<code html> +
-<​template>​ +
-  <div class="​home">​ +
-    <img alt="Vue logo" src="​../​assets/​logo.png">​ +
-    <​HelloWorld msg="​Welcome to Your Vue.js App"/>​ +
-  </​div>​ +
-</​template>​+
  
-<​script>​ +Data Binding ​is the process of connecting the view element or user interface, with the data which populates it.
-// @ is an alias to /src +
-import HelloWorld from '​@/​components/​HelloWorld.vue'+
  
-export default { +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. 
-  ​name: 'home', + 
-  ​components: ​+<code javascript>​ 
-    ​HelloWorld+export default ​function HomePage() ​
 +  ​const [inputField,​ setInputField] = useState(''​); 
 + 
 +  ​function handleChange(e) ​
 +      ​setInputField(e.target.value);​
   }   }
 +
 +  return (
 +      <div>
 +          <input value={inputField} onChange={handleChange}/>​
 +          <​h1>​{inputField}</​h1>​
 +      </​div>​
 +  );
 } }
-</​script>​ 
 </​code>​ </​code>​
  
-</solution>+===== Passing data from child to parent component =====  
 + 
 +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.  
 + 
 +<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>​ 
 + 
 +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. 
 + 
 + 
 + 
 +  
 +  
 +  
 +====== Tasks ====== 
 + 
 +  - 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 components/ that 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 ====== 
 + 
 +Please take a minute to fill in the **[[https://​forms.gle/​PNZYNNZFrVChLjag8 | feedback form]]** for this lab.
se/labs/03.1539938100.txt.gz · Last modified: 2018/10/19 11:35 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