¡Hola mundo!

Notes On React

Why React ?

React is a javascript library for creating UIs.
La gran diferencia entre libreria y framework es que el fw nos aisla del lenguaje, y react nos obliga a utilizarlo.

Web Paradigm

htmlDOM <-> JS <-> CSS -> render tree-> layout -> paint

Web Applications

El que gestiona las interfases es el lenguaje de programacion
Android -> XML. Java procesa ese xml y lo convierte en interfases visibles para el usuario

Principles of reactive functional programming.

Abstraction/ Encapsulation -> Components
Data Flow -> state

UI/ UX -> Frontend

  1. Componentes

    identificar los componentes ? Que pregunta deberíamos hacernos para identificar los componentes ?
    Si tienen comportamiento y sentido en si mismo: por ejemplo Corazoncito de twitter, que se pina de rosa cuándo le doy click. Dos estados y se repit en la interfase muchas veces.

    
    const e = React.createElement;

class LikeButton extends React.Component {
constructor(props) {
super(props);
this.state = { liked: false };
}

render() {
if (this.state.liked) {
return ‘You liked this.’;
}

return e(
  'button',
  { onClick: () => this.setState({ liked: true }) },
  'Like'
);

}
}
const domContainer = document.querySelector(‘#like-button-container’);
ReactDOM.render(e(LikeButton), domContainer);

  Comportamiento y Objetivo. Es un principio si tiene sentido en si mismo. 
  Se repite en la interfaz

2. Estados

3. Flujos

v dom poder calcular diferencias
Cuándo cambia un dato en ReactDOM, sólo esa parte se vulve a dibujar
Cuándo cambia un dato en Javascript TODO el DOM se vuelve a dibujar.

React
ReactDOM
JSX: Es una respuesta a poder integrar de frma muchoa más simple html y javascript. La sintaxis es más agradable a la vista. 
Para poder compilar JSX usamos Babel. Compatibilidad de JSX y ES5 y ES6. 

var element = <h1>Esto es un elemento</h1>
Babel lo compila cómo 
React.createElement("h1", null, "Esto es un elemento")

#### Understanding Basic Reactivity Concepts

As the web was originally designed to build Hypertext documents and not for creating Apps, first came Javascript to interact allow us to interact with the DOM in the browser. But Javascript in the browser is not reactive. So, what would be a reactive DOM ? in this example, we want to build an App that stores the name written in an input in a variable that replicates the change on every keypress event. So the initial name value in our app would be `name = ''` and every time we press a key we'd like to have our name's *state* mutated as well. if you have a value stored in a variable, and you want it to be synced.
```javascript
// $ touch example1.html
// Create an html file and add paste this code in a 

 
 

Issues !
The problem is that the DOM is bloated. Every time you touch a node just to read an attribute or a class name, or to get to a child or sibling, the browser has to search, check, parse a rather large number of proprieties and values for each node 😒
So the solution for this issue is “virtual dom “

The Virtual DOM

  • The Virtual DOM is an abstraction of the HTML DOM
  • A virtual DOM object has the same properties as a real DOM object
  • React maintains the current Dom and if some changes have to be rendered then only those changes are set in the original DOM
    Manipulating the DOM is slow. Manipulating the virtual DOM is much faster,

This is a brief description and reiteration of the Virtual DOM often mentioned alongside ReactJS.

Virtual DOM is an abstraction of the HTML DOM that selectively renders subtrees of nodes based upon state changes. It does the least amount of DOM manipulation possible in order to keep your components up to date.

https://stackoverflow.com/questions/21965738/what-is-virtual-dom

The DOM (Document Object Model) is an abstraction of structured text, which means it is made of HTML code and css. These HTML elements become nodes in the DOM. There are limitations to the previous methods of manipulating the DOM. Virtual DOM is an abstraction of the literal HTML DOM created well before React was created or used, but for our purposes we will use it in concert with ReactJS. The Virtual DOM is lightweight and detached from the DOM implementation in the browser. The Virtual DOM is essentially a screenshot (or copy) of the DOM at a given time. A way to look at it from a developers perspective is the DOM is the production environment and the Virtual DOM is the local (dev) environment. Each time the data changes in a React app a new Virtual DOM representation of the user interface is created.

The most basic method needed in order to create a static component in ReactJS are:

You must return code from the render method. You must convert every class to className since class is reserved word in JavaScript. Aside from the more major changes there are minor differences between the two DOMs including three attributes appearing in the Virtual DOM but not in the HTML DOM (key, ref and dangerouslySetInnerHTML).

An important thing to understand when working with the Virtual DOM is the difference between ReactElement and ReactComponent.

ReactElement

A ReactElement is a light, stateless, immutable, virtual representation of a DOM Element.
ReactElement - This is the primary type in React and resides in the Virtual DOM.
ReactElements can be rendered into HTML DOM

var root = React.createElement('div');
ReactDOM.render(root, document.getElementById('example'));

JSX compiles HTML tags into ReactElements

var root =

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

ReactComponent

ReactComponent - ReactComponent's are stateful components.
React.createClass is considered a ReactComponent.
Whenever state changes the component is rerendered.
Whenever a ReactComponent has a state change, we want as little change to the HTML DOM as possible so ReactComponent is converted to the ReactElement which can then be inserted to the Virtual DOM, compared and updated fast and easily.

When React knows the diff - it's converted to the low-level (HTML DOM) code, which is executed in the DOM.

share improve

A minimal React implementation

Performance : using React will lead to a fast user interface without doing much work to specifically optimize for performance
Simplicity : Reactjs it’s based component , with simple plain JavaScript code
All the power of HTML, CSS and Javascript together inside the component:
It’s easy to learn : Anyone who have some background with HTML CSS and JavaScript , can Learn Reactjs ( it’s dedicated for Developers and Designers and Microsoft engineers: it’s dedicated for Developers, Designers and Microsoft engineers 😗
increasing development speed : ReactJS allows us to create reusable UI components that can be used in many web pages
Testability : ReactJS applications are super easy to test

The example we've been working on could be translated easily to react. Just create a new file example4.html add the following lines.

<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { 
      name: '' 
    };
  }

  render() {
    return React.createElement(
      'div',
      null,
      [
        React.createElement('div', {className:'name-div'}, this.state.name),
        React.createElement(
          'input',
          {
            placeholder: 'Enter your name',
            type: 'text', 
            autoFocus: true,
            value:this.state.name,
            onKeyPress: e => {
              let name = `${this.state.name}${e.key}`
              this.setState({name});
            }
          },
          null
        ),
        React.createElement(
          'button',
          {
            onClick: () => this.setState({name:''})
          },
          'Clear'
        )
      ]
    );
  }
}
const domContainer = document.getElementById('root');
ReactDOM.render(React.createElement(App), domContainer);

// This sample App could also be written in this way

const App = props => {

  const [name, setName] = React.useState('');

  return React.createElement(
    'div',
    null,
    [
      React.createElement('div', {className:'name-div'}, name),
      React.createElement(
        'input',
        {
            placeholder: 'Enter your name',
            type: 'text', 
            autoFocus: true,
            value:name,
            onKeyPress: e =>  setName(`${name}${e.key}`)
          },
        null
      ),
      React.createElement(
        'button',
        {
          onClick: () => setName('')
        },
        'Clear'
      )
    ]
  );
}

const domContainer = document.getElementById('root');
ReactDOM.render(React.createElement(App), domContainer);

JSX && Babel

As the official documentation says, JSX element is just syntactic sugar for calling React.createElement(component, props, ...children). React components are written in JSX, a JavaScript extension syntax allowing easy quoting of HTML

  • JSX is a preprocessor step that adds XML syntax to JavaScript. You can definitely use React without JSX but JSX makes React a lot more elegant.
  • By using JSX one can write the following JSX/JavaScript code:

    var nav = (
    <ul id="nav">
      <li><a href="#">Home</a></li>
      <li><a href="#">About</a></li>
      <li><a href="#">Clients</a></li>
      <li><a href="#">Contact Us</a></li>
    </ul>
    );

    Babel is a JavaScript compiler that will transform it into this: 😙

    ar nav = React.createElement(
    "ul",
    { id: "nav" },
    React.createElement(
      "li",
      null,
      React.createElement(
         "a",
         { href: "#" },
         "Home"
      )
    ),
    React.createElement(
      "li",
      null,
      React.createElement(
         "a",
         { href: "#" },
         "About"
      )
    ),
    React.createElement(
      "li",
      null,
      React.createElement(
         "a",
         { href: "#" },
         "Clients"
      )
    ),
    React.createElement(
      "li",
      null,
      React.createElement(
         "a",
         { href: "#" },
         "Contact Us"
      )
    )
    );

    We can use JSX just by adding the following tags

    bash
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
    // and then add <script type="text/babel">
    
    class App extends React.Component {
    constructor(props) {
      super(props);
      this.state = { 
        name: '' 
      };
    }
    
    render() {
      return (
        <div>
          <div className="name-div">{this.state.name}</div>
          <input 
            placeholder="Enter your name" 
            type="text" 
            auto-focus="true" 
            value={this.state.name} 
            onKeyPress={e => {
              let name = `${this.state.name}${e.key}`
              this.setState({name});
            }} 
          />
          <button 
            onClick={() => this.setState({name:''})}
          >
          Clear</button>
        </div>
      );
    }
    }
    const domContainer = document.getElementById('root');
    ReactDOM.render(React.createElement(App), domContainer);
    
    </script>

    Now that we've rewritten the initial App using JSX. React's premise is to separat concerns, not technologies, with Components that wrap both markup and logic.
    In our example codes, we declare a variable called name and then use it inside JSX by wrapping it in curly braces <div>{this.state.name}</div>. But we can also put JS expressions inside curly braces, like {2 + 2}, {user.firstname}, {capitalizeName(user)} as well as using JSX inside ifs and for loops.

    if (userIsLoggedIn) {
    return <h1>Hello, {user.name}</h1>
    } else {
    return <h1>Hello Stranger</h1>
    }

    JSX attributes are specified with quotes for string values <div tabIndex="0"> or curly braces if they are the result an expression <img src={user.avatarImg}>. The attributes are specified with camelCase convention (class -> className).
    JSX represents objects, as Babel compiles JSX React Elements down to React.createElement(type, props, ...children) calls.

    // So this code
    const element = (
    <h1 className="greeting">
    Hello, world!
    </h1>
    );
    // will be compiled to a createElement(type, props, ...children)
    const element = React.createElement(
    'h1',
    {className: 'greeting'},
    'Hello, world!'
    );

Components

Components are the heart and soul of React. They are JavaScript functions that accept arbitrary arguments (called 'props') and return JSX (React elements describing what should appear on the screen).
Component :
“Everything is a Component “

What is Component ?

  • Self-contained reusable building blocks of web application
  • Components let you split the UI into independent, reusable pieces
  • a component is a JavaScript class or function
    So my advice for you before you start coding , you should split your UI into components , reusable components !

Elements != Components

React elements are what components are 'made of'. In the examples above we rendered our entire App inside a root node ReactDOM.render(element, document.getElementById('root')). everything inside 'root DOM' will be managed by React DOM. React Apps usually have one root node, but you can have as many root nodes as you like.
React DOM Will only update when necessary, and only the nodes necessary to bring the DOM to the desired state.

Function and Class Components

A component can be defined as a function or a ES6 class that extends React.Component (inheriting some methods that we'll see later on). For now, both of these examples are equivalent. By convention, we name Components in PascalCase. The bottom line is that both function and class Components have to return some JSX.

// Functional Component
function HelloComponent (props) {
  return <h1>Hello, {props.name}</h1>
}
// Class Component
class HelloComponent extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>
  }
}

In the examples above we have only encountered React elements that represent DOM tags, such as const element = <div/> but elements can also represent user defined components const element = <Hello name="Santiago" />. When React sees an element
representing an user-defined component it passes JSX attributes and children to this component as a single object .We call this object props.

function HelloComponent (props) {
  return <h1>Hello, {props.name}</h1>
}
const element = <HelloComponent name="Santiago" />;
ReactDOM.render(
  element,
  document.getElementById('root')
);

The steps for this example would be something like

  1. We call ReactDOM.render with the <Hello name="Santiago" /> element
  2. React calls the <Hello /> component with {name:'Santiago'} as props
  3. <Hello /> component returns a <h1>Hello, {props.name}</h1> as a result
  4. ReactDOM updates the DOM to render <h1>Hello, Santiago</h1>

Composing Components

Components can refer to other components in their output. Typically, new React apps have a single App component that renders smaller components, extracting larger components into smaller ones. If a part of the UI is used several times (Button, Panel, Avatar) or is complex enough on it's own (FeedHistory, Comments) its a good candidate to be a resuable component.

Props are Read-Only

A Component, either a class or function, must never modify its own props. They must remain pure and return the same output based on the same input. Such functions are called "pure", because such function do not change the inputs. React components must act like pure functions with respect to their props.

Data Flow

The flow in React is one-directional. We maintain a hierarchy of components, in which each component depends only on its parent and its own internal state. We do this with properties: data is passed from a parent to its children in a top-down manner. If an ancestor component relies on the state of its descendant, one should pass down a callback to be used by the descendant to update the ancestor.

The same concept applies to React Native. As long as we are building our application purely within the framework, we can drive our app with properties and callbacks. But, when we mix React Native and native components, we need some specific, cross-language mechanisms that would allow us to pass information between them.

State and Lifecycle

As React components must act like pure functions regarding their props, so that oyu can't change the value of a property from within the component itself, state is mutable. So, props are immutable while state is mutable. The state object is defined internally and should change dinamically in React components.

class Clock extends React.Component {
  // Class components should always call the base constructor with props
  constructor(props){
    super(props);
    // The class constructor assigns the initial this.state:
    this.state = {
      date:new Date()
    }
  }
  render () {
    return (
      <div>
        <h1>Hello World</h1>
        <h2>It is {state.date.toLocaleTimeString()}</h2>
      </div>
    )
  }
};

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

State and props are used togheter to control data flow with React Components. While props are used tu pass immutable data to child elements, state allow components to dynamically update and propagate changes in unidirectional patterns.

Lifecycle Methods

One important factor in large applications is to free up resources taken by the components when they are destroyed. If we set a timer function when the clock is rendered for the first time, when it's mounted we'd want to clear it when the clock is removed or unmounted. We can declare special methods (Lifecycle Methods) on the component class to run some code when a component mounts and unmounts.
Each component in React has a lifecycle which you can monitor and manipulate during its three main phases.

The three phases are: Mounting, Updating, and Unmounting

React's common lifecycle methods are the series of events that happen from the birth of a React component to its death.

  • Mounting
    1. constructor()
    2. getDerivedStateFromProps()
    3. render()
    4. componentDidMount()
  • Updating
    1. getDerivedStateFromProps()
    2. shouldComponentUpdate()
    3. render()
    4. getSnapshotBeforeUpdate()
    5. componentDidUpdate()
      • Unmounting
    6. componentWillUnmount()

Mounting means putting elements into the DOM. React Components have four built-in methods that are called whenever a component is mounted. Only render is mandatory, the rest are optional.

  1. construct() is called before anything else. The natural place to set up the initial state and other initial values. It is called with the props, as arguments, and you should always start by calling the super(props) to initiate the parent's constructor method.

  2. getDerivedStateFromProps(props, state) is called right before rendering the element(s) in the DOM, natural place to set the state object based on the initial props. It takes state as an argument, and returns an object with changes to the state.

  3. render() method is the most used lifecycle method in all React classes, as it is the only required method within a class component in React. As the name suggests it handles the rendering of your component to the UI. It happens during the mounting and updating of your component. You cannot setState() within a render() or modify the component state within the render(). the render() method returns JSX that is displayed in the UI. A render() can also return a null if there is nothing to render for that component.

  4. componentDidMount() is called as soon as the component is mounted and ready. This is a good place to initiate API calls, if you need to load data from a remote endpoint. Unlike the render() method, componentDidMount() allows the use of setState(). Calling the setState() here will update state and cause another rendering but it will happen before the browser updates the UI. This is to ensure that the user will not see any UI updates with the double rendering.
    You can modify the component state within the componentDidMount(), but use it with caution.

componentDidUpdate() is invoked as soon as the updating happens. The most common use case for the componentDidUpdate() method is updating the DOM in response to prop or state changes. You can call setState() in this lifecycle, but keep in mind that you will need to wrap it in a condition to check for state or prop changes from previous state. Incorrect usage of setState() can lead to an infinite loop.

componentWillUnmount() is called just before the component is unmounted and destroyed. If there are any cleanup actions that you would need to do, this would be the right spot. This component will never be re-rendered and because of that we cannot call setState() during this lifecycle method.

shouldComponentUpdate(props, state) Anytime setState() is called, the component re-renders by default. The shouldComponentUpdate() method is used to let React know if a component is not affected by the state and prop changes.

static getDerivedStateFromProps() a safer alternative to the previous lifecycle method componentWillReceiveProps().
It is called just before calling the render() method. This is a static function that does not have access to “this“. getDerivedStateFromProps() returns an object to update state in response to prop changes. It can return a null if there is no change to state.

getSnapshotBeforeUpdate() a safer alternative to the previous lifecycle method componentWillUpdate().

React Lifecycle
React Lifecycle Methods – A Deep Dive

Functional Components / Class Components

With React, you can make components using either classes or functions. Originally, class components were the only components that could have state. But since the introduction of React's Hooks API, you can add state and more to function components.

Hooks were introduced in React Native 0.58., and because Hooks are the future-facing way to write your React components, we wrote this introduction using function component examples. Where useful, we also cover class components under a toggle like so:

React Hooks allow to use functional Components only. Previously you had to use class component if you wanted to use state or lifecycle methods. Hooks allow you to create every component as a functional component.
The react ecosystem is using functional components, when you creat a new react app it used to be a class based
component and now it's a fuctional components.
The main difference is that class based components have lifecycle hooks, and functional components don't. The
difference is that even though both approaches can achieve the same results a Functional component has to return some JSX

You can use useEffect() to copy the behaviour of componentDidMoun and componentDidUpdate.
useEffect runs after every render cycle. A second argument makes it run once. Whenver this data changes we want to execute this function.

class UsersComponent extends React.Component {
  constructor() {
    this.state = {
      users:[]
    };
  }
  componentDidMount () {
    // api example call
  }
  render (
    return(
      <View>
        {
          this.state.users.map(i => {
            // print articles
          })
        }
      </View>
    );
  )
}
const UserComponent = props => {
  const [users, setUsers] = React.useState([]);

  useEffect(() => {
    // api example call
  }, []);

  return(
    <View>
      {
        this.state.users.map(i => {
          // print articles
        })
      }
    </View>
  );

}
import React, { useState, useEffect } from "react";
export default props => {
  console.log("componentWillMount");
  console.log("componentWillReceiveProps", props);
  const [x, setX] = useState(0);
  const [y, setY] = useState(0);
  const [moveCount, setMoveCount] = useState(0);
  const [cross, setCross] = useState(0);
  const mouseMoveHandler = event => {
    setX(event.clientX);
    setY(event.clientY);
  };
  useEffect(() => {
    console.log("componentDidMount");
    document.addEventListener("mousemove", mouseMoveHandler);
    return () => {
      console.log("componentWillUnmount");
      document.removeEventListener("mousemove", mouseMoveHandler);
    };
  }, []); // empty-array means don't watch for any updates
  useEffect(
    () => {
      // if (componentDidUpdate & (x or y changed))
      setMoveCount(moveCount + 1);
    },
    [x, y]
  );
useEffect(() => {
    // if componentDidUpdate or componentDidMount
    if (x === y) {
      setCross(x);
    }
  });
  return (
    <div>
      <p style={{ color: props.color }}>
        Your mouse is at {x}, {y} position.
      </p>
      <p>Your mouse has moved {moveCount} times</p>
      <p>
        X and Y positions were last equal at {cross}, {cross}
      </p>
    </div>
  );
};
state + setState(...) useState(...)
componentDidMount() useEffect(() => {}, [])
componentWillUpdate() useEffect(() => {})
componentWillUnmount() useEffect(() => { return () => {}})

state + setState(...) => useState(...)
componentDidMount() => useEffect(...)

useEffect -> componentDidMount()

The Reactjs Ecosystem

outside of Reactjs , There is other cool tools

  • React-router : the standard routing library for React.
  • React-Native : lets you build mobile apps using only JavaScript. It uses the same design as React, letting you compose a rich mobile UI from declarative components
  • React-VR : Create exciting 360 and VR experiences using React
  • create-react-app : a tool built by developers at Facebook to help you build React applications. It saves you from time-consuming setup and configuration

References

https://reactjs.org/docs/components-and-props.html
https://www.w3schools.com/react/react_lifecycle.asp
https://medium.com/@Ahmedrebai/my-first-reactjs-blog-part1-e72fae2895c0

https://medium.com/simars/react-hooks-manage-life-cycle-events-tricks-and-tips-7ed13f52ba12

Sumate a la conversación

2 comentarios

Dejá un comentario

Responder a Santiago Bayazbakian Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *