React

From Sinfronteras
Revision as of 19:14, 23 June 2019 by Adelo Vieira (talk | contribs) (index tsx and index html)
Jump to: navigation, search

https://reactjs.org/docs/react-component.html

React (also known as React.js or ReactJS) is a JavaScript library (not a Framework) for building user interfaces. It is maintained by Facebook.

React can be used as a base in the development of single-page or mobile applications.

React allows us to build component-based user interfaces (UI). A component is a self-contained standalone piece of functionality. For example, a drop-down menu or a collapsible panel can be implemented as a React component.


To understand what is React, we can said that, in general, React generates html using JS or TypeScript. You can choose if you want to do generate the html in the client site or in the server site. This course is focused about how to do it in the client site. In the sever site is more complicate and it is done just in some particular case.



Execute some JS commands from the Web Browser console

You can use JS to access and modify the html and the css. You can, for example, create a new html element in the DOM.

Let's see how that works. From the Web Browser console, you can display the structure of the page and make changes on it. For example, you can display the body of the web page by executing:

document.body


You can make changes in the background color with:

document.body.bgcolor = "red"



Single Web Application

We said that we are creating a single web page App because what the server send to the client is only one page, which is that index.html page. Then, the Reanc Application can have as many pages as we want, but they are all generated in the client site.



The main characteristics of React

  • SimplicityReact: can seem very different from other libraries at first glance but its API is minimaland its programming model is actually quite simple. As a result, learning React or investigating the causes of an issue can be relatively simple tasks.
  • Component-based: We are going to learn more component-based UI development in the following section.
  • JavaScript APIs over custom APIs: The React API tries to use standard JavaScript APIs instead of custom APIs. For example, in React we can implement a loop while rendering elements using theJavaScript map function, instead of a custom API such as the ng-repeat API in Angular.
  • Highly influenced by functional programming principles: React is highly influenced by functional programming. The implications of these influences are very noticeable in many of the React API and design principles. The following are some of the main characteristics of React that can be considered as a direct result of its Functional Programming roots:
  • Immutability: React encourages us to use immutable objects and avoid state mutations.
  • Stateless: In React we have to worry a lot about the application's state. React encourages us to try to avoid it and to push it to the boundaries of our system.
  • Declarative over imperative: React encourages a declarative programming style over an imperative programming style.



Component-based UI development

React allows us to implement (SPAs) using a UI programming model known as component-based UI development. The main building block in a component-based UI development library or framework is a web component. A web component is a piece of the UI that is isolated, and self-contained. A web component encapsulates the HTML, CSS, and JavaScript.

When we build a component-based UI, we start by implementing the most basic web components such as inputs and buttons. We can call these components primitives. We then combine primitive components to build more sophisticated components and eventually we compose multiple advanced components to create the pages in our web application. However, the pages themselves can also be implemented as web components.



Virtual DOM

React uses a pattern known as virtual DOM (VDOM) (DOM: Document Object Model) where a virtual representation of a UI is kept in memory and synced with the real DOM by a library such as ReactDOM. The synchronization process is called reconciliation.

The virtual DOM allows us to update the DOM in a declarative way, so we don’t need to worry about how React updates the DOM internally. React can figure out how to efficiently update the DOM from the previous HTML tree to the next version in a very efficient way. You may have heard about React Fiber is the new reconciliation engine in React 16. Its maingoal is to enable incremental rendering of the virtual DOM.

It is important not to confuse the virtual DOM with the shadow DOM. The Shadow DOM is a browser technology designed primarily for scoping variables and CSS in web components. The virtual DOM is a concept implemented by libraries in JavaScript on top of browser APIs.



The main benefits of React

  • Simplier applications: The React programming model can simplify the development of complex web applications. In particular, when compared against other technologies that don't use a component-based web development model.
  • Fast user interfaces: The React rendering engine is very fasts and efficient. Using React can helpus to achieve an outstanding web application performance.
  • Re-usability: Web components are highly reusable by nature. They provide an abstraction for apiece of UI functionality so it can be re-used.
  • Test ability: React is highly influenced by some functional programming ideas. As a result, React encourages the implementation of stateless components and immutable properties. We will learn more about these principles later, but for now, we can say that these principles help our components to be unit tested with ease.
  • Powerful abstractions: JSX and the Virtual DOM a allow us to write declarative code and abstract us away from the DOM rendering and reconciliation details.
  • Ecosystem and community: The React community and there is a huge number of libraries and frameworks with a high degree of diversity.
  • Consistent user experience: Web components can help to create a consistent user experience across an entire application or even an organization as a whole. Web components can help our applications to adhere to style guides with ease.



The React ecosystem

As we have already learned, React is a library, not a framework.

React is inspired by the UNIX philosophy:

Do one thing and do it well.

So React is very good at one thing: allow developers to build UI components. However, React doesn't tinclude support for some of the most common features in SPAs. For example, React doesn't include any routing or navigation-related features, data fetching features or state management features among many others.

If we want to build a real-world professional SPA, it is highly likely that we will need some additionallibraries. The good news is that the React ecosystem is very extensive and we will almost certainly findan already existing library that can do what we are looking for.

The React ecosystem also follows the UNIX philosophy. This means that we will have to install a numberof tools because each tool will only do one thing. For example, the react-dom module renders the React application using the DOM API while the react-router-dom module can be used to implement routing in web browsers. These modules do only one thing, but they do it very well.

This architectural style has some pros and cons. We can say that React allows us to select the best tool for the job and does't decide anything for us. React gives us more options and, as a result, getting started with React can be being more time-consuming.

Also, because the Raact ecosystem is very diverse and sometimes each project comes from a different author, there is a higher risk of projects being abandoned.



Install React

We need to install the create-react-app command using npm. Because we are going to invoke the create-react-app command from our terminal, we need to install it as a global dependency using the -g flag:

npm install -g create-react-app



Creating a React project

In the past, creating a React application used to be a very tedious and complicated task. However,things have gotten much better over time and today we can auto-generate an entire React application in just a few minutes using the create-react-app command.

We are going to use the create-react-app to scaffold out a basic React app from the terminal in just a couple of minutes.

To generate a new React application with TypeScript support, we need to execute the following command:

create-react-app myreactapp --typescript

The preceding command will generate a folder named myreactapp the current directory. This operation can take a few minutes, so please be patient.

It is recommended to create the application in a directory that is unlikely to be affected by permissions-related restrictions. For example, you can use the CODE directory under your user's home directory (~/CODE/home).

If everything works correctly, a new folder named myreactapp should be created in the current directory and it should contain the following files and folders:

.
|--README.md
|--node_modules
|   `-- ...
|--public
|   |--favicon.ico
|   |--index.html
|   `--manifest.json
|--src
|   |--App.css
|   |--App.test.tsx
|   |--App.tsx
|   |--index.css
|   |--index.tsx
|   |--logo.svg
|   |--react-app-env.d.ts
|   `--serviceWorker.ts
|--package-lock.json
|--package.json
`--tsconfig.json

It is essential to ensure that the extension of some of the files such as the index.tsx is .tsx andnot .js. When we execute the create-react-app with the --typescript flag, we are creating a TypeScript project, and the file extension will be .tsx. However, if we forget the flag, the create-react-app command will generate a JavaScript project and the extension of the index.tsx file will be .js instead of .tsx. If the file extension is wrong, you should delete the entire project folder and create a new project using the --typescript flag.



package json

The project generated by the create-react-app command contains the following package.json file:

{
  "name": "myreactapp",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@types/jest": "24.0.6",
    "@types/node": "11.9.4",
    "@types/react": "16.8.4",
    "@types/react-dom": "16.8.2",
    "react": "^16.8.2",
    "react-dom": "^16.8.2",
    "react-scripts": "2.1.5",
    "typescript": "3.3.3"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not ie <= 11",
    "not op_mini all"
  ]
}

As we can see in the preceding code snippet, the auto-generated package.json file contains some default npm scripts commands:

  • npm run start can be used to start running our React application using a local development server.
  • npm run build can be used to build our React application into an application bundle that we can deploy to a hosting provider.
  • npm run test can be used to execute the unit and integration tests in our React application.
  • npm run eject can be used to make some internal configuration public. One example is the Webpack configuration file. Webpack is a tool that is used to compile, minimize and bundle front-end applications into highly optimized files. We do this because it helps to reduce the loading times of our applications. However, configuring Webpack is a complex and tedious task. The create-react-app project hides this complexity from us. We are free to expose the complexity using the eject npm script.


Please note that it is not possible to rollback the changes performed by the eject npm script command.



tsconfig json

tsconfig json is another important file generated by the create-react-app command. This file contains the TypeScript compiler options.



Run the App

Now that we know about the npm scripts generated by create-react-app in the package.json file, we are going to run our application using the start command. When in the linux terminal you execute npm run start, this execute react-scripts start and start the App in the Web Browser:

npm run start


At this point, we should be able to see our React application displayed on the screen:

The default application generated by the create-react-app command

As we can see in the default application, the following message is displayed on the screen:

Edit src/App.tsx and save to reload

The local web server started by the npm run start command automatically reloads the React application when a change in the source code is detected. This is very similar to the way nodemon behaves as we learned during the first part of this course.



JSX

https://reactjs.org/docs/introducing-jsx.html

const element = <h1>Hello, world!</h1>;

This funny tag syntax is neither a string nor HTML. It is called JSX, and it is a syntax extension to JavaScript. We recommend using it with React to describe what the UI should look like. JSX may remind you of a template language, but it comes with the full power of JavaScript. JSX produces React "elements". We will explore rendering them to the DOM.



App tsx

We are now going to take a look to the source code of the src/App.tsx file that was generated by the create-react-app command:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <p>
            Edit <code>src/App.tsx</code> and save to reload.
          </p>
          <a
            className="App-link"
            href="https://reactjs.org"
            target="_blank"
            rel="noopener noreferrer"
          >
            Learn React
          </a>
        </header>
      </div>
    );
  }
}

export default App;


Let's ignore the entire code snippet and only focus on the following section for now:

<p>
  Edit <code>src/App.tsx</code> and save to reload.
</p>


This is the sentence that was displayed on the screen when we started the local web server. We are going to change the preceding code snippet to something like the following:

<p>
  Hello React!
</p>


Then, if we save the changes to the file, our browser will automatically be refreshed and we will see thenew sentence displayed on the screen.



index tsx and index html

index.tsx is the application entry point:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<App />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: http://bit.ly/CRA-PWA
serviceWorker.unregister();


In general, React generates html (I think «render» means "to execute the code and generate the html"). To render the App in the client site we need:

import ReactDOM from 'react-dom';

react-dom have a method call render (ReactDom.render) that is the method that executes the code and generates the html:

ReactDOM.render(<App />, document.getElementById('root'));

In the previous line, we are basically saying, we want to render the <App /> component, and we want to render it into document.getElementById('root') (so into the Element of the Document with ID 'root'). In other words, there is a html page, and in this page there is an element with ID root and inside this element is where the React App is going to be run. You can check this by going to the public/index.html file. Notice in this file:

  • <div id="root"> <d/iv>  : Inside this <div> is where ReactDOM.render is going to place the html generated by React.
  • <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />  : That line is going to load the manifest.json, which is going to render the React Applicatino into the above <div> .


We said that we are creating a single web page App because what the server send to the client is only one page, which is that index.html page. Then, the Reanc Application can have as many pages as we want, but they are all generated in the client site.


Let's make some change in index.tsx:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';


const element = <h1>Helo</h1>;

ReactDOM.render(element, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: http://bit.ly/CRA-PWA
serviceWorker.unregister();


With the above changes, what is going to be rendered into document.getElementById('root') is element. So the Application in your web browser is going to show only "Hello".


That was just an example, but what we usually do is something like this:

class MyComponent extends React.Component {
    public render(){
        const element = <h1>Helo</h1>;
        return element;
    }
}

ReactDOM.render(<MyComponent/>, document.getElementById('root'));

This component becomes a html tag, and that is why we can render it this way: <MyComponent/>. Now we can use our <MyComponent/> html tag as many times as we want and so reuse code.

In the above example we render our <MyComponent/> tag, but we can also use standard html tags, <div> for example. We can do something like this:

class MyComponent extends React.Component {
    public render(){
        const element = <h1>Helo</h1>;
        return element;
    }
}

ReactDOM.render(
    <div>
        <MyComponent/>
        <MyComponent/>
        <MyComponent/>
        <MyComponent/>
    </div>,
    document.getElementById('root')
);


Let's do a more realistic example. Suppose that we want to create a Header with a particular style. In a company, for example, we want to make sure that every time someone need a header, this is going to be the same. We don't want the header in one page to look one way and in a different way in another page. We can for example define the CSS style of our component this way:

class MyComponent extends React.Component {
    public render(){
        const style: React.CSSProperties = {
            borderBottom: "1px solid blue"
        };
        const element = <h1 style={style}>Hello</h1>;
        return element;
    }
}

ReactDOM.render(
    <div>
        <MyComponent/>
        <MyComponent/>
        <MyComponent/>
        <MyComponent/>
    </div>,
    document.getElementById('root')
);

It is very important to notice that:

  • The value of the variable style (that is an object) is going to be the CSS of our component.
  • React.CSSProperties is the type of the variable (style) we are creating. Remenber that in TypeScript we need to define the type of the variable.
  • Also, notice that in CSS, the attribute we are defining would be border-bottom, but in react (JSX) is borderBottom.


We can also define argument in our components.



Components and Props

Para probar códigos: https://codepen.io/pen

https://reactjs.org/docs/components-and-props.html

Components let you split the UI into independent, reusable pieces, and think about each piece in isolation. This page provides an introduction to the idea of components.

Conceptually, components are like JavaScript functions. They accept arbitrary inputs (called "props") and return React elements describing what should appear on the screen.



Function and Class Components

The simplest way to define a component is to write a JavaScript function:

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

This function is a valid React component because it accepts a single props (which stands for properties) object argument with data and returns a React element. We call such components function components because they are literally JavaScript functions.


You can also use an ES6 class to define a component:

class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}


The above two components are equivalent from React's point of view.


Classes have some additional features that we will discuss in the next sections. Until then, we will use function components for their conciseness.



Rendering a Component

Previously, we only encountered React elements that represent DOM tags:

const element = <div />;

However, elements can also represent user-defined components:

const element = <Welcome name="Sara" />;

When React sees an element representing a user-defined component, it passes JSX attributes to this component as a single object. We call this object "props".

For example, this code renders "Hello, Sara" on the page:

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

const element = <Welcome name="Sara" />;
ReactDOM.render(
  element,
  document.getElementById('root')
);

Let's recap what happens in this example:

  • We call ReactDOM.render() with the <Welcome name="Sara" /> element.
  • React calls the Welcome component with {name: 'Sara'} as the props.
  • Our Welcome component returns a <h1>Hello, Sara</h1> element as the result.
  • React DOM efficiently updates the DOM to match <h1>Hello, Sara</h1>.


Note: Always start component names with a capital letter. React treats components starting with lowercase letters as DOM tags. For example, <div /> represents an HTML div tag, but <Welcome /> represents a component and requires Welcome to be in scope. To learn more about the reasoning behind this convention, please read JSX In Depth.



Composing Components

Components can refer to other components in their output. This lets us use the same component abstraction for any level of detail. A button, a form, a dialog, a screen: in React apps, all those are commonly expressed as components.

For example, we can create an App component that renders Welcome many times:

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

function App() {
  return (
    <div>
      <Welcome name="Sara" />
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);



Extracting Components

Don’t be afraid to split components into smaller components.

For example, consider this Comment component:

function Comment(props) {
  return (
    <div className="Comment">
      <div className="UserInfo">
        <img className="Avatar"
          src={props.author.avatarUrl}
          alt={props.author.name}
        />
        <div className="UserInfo-name">
          {props.author.name}
        </div>
      </div>
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}


This component can be tricky to change because of all the nesting, and it is also hard to reuse individual parts of it. Let's extract a few components from it.

First, we will extract Avatar:

function Avatar(props) {
  return (
    <img className="Avatar"
      src={props.user.avatarUrl}
      alt={props.user.name}
    />
  );
}

The Avatar doesn't need to know that it is being rendered inside a Comment. This is why we have given its prop a more generic name: user rather than author.

We recommend naming props from the component’s own point of view rather than the context in which it is being used.


We can now simplify Comment a tiny bit:

function Comment(props) {
  return (
    <div className="Comment">
      <div className="UserInfo">
        <Avatar user={props.author} />
        <div className="UserInfo-name">
          {props.author.name}
        </div>
      </div>
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}


Next, we will extract a UserInfo component that renders an Avatar next to the user's name:

function UserInfo(props) {
  return (
    <div className="UserInfo">
      <Avatar user={props.user} />
      <div className="UserInfo-name">
        {props.user.name}
      </div>
    </div>
  );
}


This lets us simplify Comment even further:

function Comment(props) {
  return (
    <div className="Comment">
      <UserInfo user={props.author} />
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}


Extracting components might seem like grunt work at first, but having a palette of reusable components pays off in larger apps. A good rule of thumb is that if a part of your UI is used several times (Button, Panel, Avatar), or is complex enough on its own (App, FeedStory, Comment), it is a good candidate to be a reusable component.



Component

https://reactjs.org/docs/react-component.html

React lets you define components as classes or functions. Components defined as classes currently provide more features which are described in detail on this page. To define a React component class, you need to extend React.Component:

class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

The only method you must define in a React.Component subclass is called render(). All the other methods described on this page are optional.