Archivo de la categoría: JavaScript

React JS

Instalar React

$ yarn add eslint --dev
$ yarn add react react-dom --dev
$ yarn add @babel/preset-react@^7.0.0 --dev
$ yarn add eslint-plugin-react --dev
$ yarn add prop-types --dev 
$ yarn add babel-plugin-transform-react-remove-prop-types --dev 
$ yarn add sass-loader@^11.0.0 sass --dev 
Agrega este contenido dentro de .eslintrc.js:  

module.exports = { extends: ['eslint:recommended', 'eslint-plugin-react:react/recommended'], parserOptions: { ecmaVersion: 6, sourceType: 'module', ecmaFeatures: { jsx: true } }, env: { browser: true, es6: true, node: true }, rules: { "no-console": 0, "no-unused-vars": 0 } };

Crear App

$ npx create-react-app myapp
$ cd myapp
$ yarn start

// https://saurabhshah23.medium.com/react-js-architecture-features-folder-structure-design-pattern-70b7b9103f22

React & Symfony

En webpack.config.json agregar:
//enable React
.enableReactPreset()

// eliminar proptypes en produccion
.configureBabel((babelConfig) => {
    if (Encore.isProduction()) {
        babelConfig.plugins.push(
            'transform-react-remove-prop-types'
        );
    }
})

React Components

export defualt class AComponent extends React.Component {

    construct(props) {
        super(props);
        this.state = {
            row = null   
        }
    }

    //Este método es obligatorio
    render() {
    }
}

Functional Components

const MyButton = ({ disabled, text }) => (
    
);
MyButton.defaultProps = {
    text: 'My Button',
    disabled: false
};
export default MyButton;

Props y state

Props son valores que recibe el componente que son inmutables, el componente no las va a cambiar
cuando se realiza un evento.
State si las puede cambiar el componente

//Cuando se va a cambiar el state pero se va a utilizar un valor del mismo state se tiene que pasar con una callback
//donde state es el estado actual
this.setState(state => ({
    ...state,
    fourth: state.doneMessage
})

Además hay que crear nuevos objetos cuando queremos modificar un objeto del state, para mantener la inmutabilidad

//...
this.state = {
    data : [
        {//..},
        {//..},
    ]
}

Si queremos agrega un elemento a data hay que hacerlo de esta manera

someFunction() {
    const newData = [...this.state.data, {/...}]
}
Por que si lo hacemos así

const newData = this.state.data;
newData.push({//..})
Estamos modificando el objeto original.


Modificar un objeto dentro de un array manteniendo la inmutabilidad

someFunction(id) {
    this.setState((prevState) => {
        return {
            data: prevState.data.map(d => { -> map nos devuelve una copia (explicacion anterior)
                if (d.id !== id) {
                    return d;
                }
                //Pero dentro de esa copia los objetos son los originales entonces con Object assing devuelve un nuevo objeto donde el 3er objeto es combinado al 2do y el 2do al 1ero
                return Object.assign({}, d, {someProp: true});
            })
      };
});

lifecycles

getDerivedStateFromProps() : This method allows you to update the state of
the component based on property values of the component. This method is called
when the component is initially rendered and when it receives new property
values.
render() : Returns the content to be rendered by the component. This is called
when the component is first mounted to the DOM, when it receives new
property values, and when setState() is called.
componentDidMount() : This is called after the component is mounted to the
DOM. This is where you can perform component initialization work, such as
fetching data.
shouldComponentUpdate() : You can use this method to compare new state or
props with current state or props. Then, you can return false if there's no need to
re-render the component. This method is used to to make your components more
efficient.
getSnapshotBeforeUpdate() : This method lets you perform operations
directly on DOM elements of your component before they're actually committed
to the DOM. The difference between this method and render() is that
getSnapshotBeforeUpdate() isn't asynchronous. With render() , there's a
good chance that the DOM structure could change between when it's called and
when the changes are actually made in the DOM.
componentDidUpdate() : This is called when the component is updated. It's rare
that you'll have to use this method.

Portals

https://reactjs.org/docs/portals.html
A component that should be rendered as a dialog probably
doesn't need to be mounted at the parent. Using a portal, you can control specifically where
your component's content is rendered

Paquetes utiles

$ npm install --save redux-saga
$ npm install --save redux
$ npm i -S react-redux
$ npm i -D redux-devtools

React Native

Crear aplicación:

$ npx react-native init my-project
$ cd my-project
$ yarn start

Abrir emulador:


//https://developer.android.com/studio/run/emulator-commandline
//Ir a la carpeta del emulador de android
$ cd ~/Android/Sdk/emulator
//podemos listar nuestros dipositivos
$ ./emulator -list-avds
//Ejecutar el dispositivo
$ ./emulator -avd NOMBRE_DISPOSITIVO
//Otra opción para ejecutar el dispositivo
//Performs a cold boot, and saves the emulator state on exit.
$ ./emulator -avd NOMBRE_DISPOSITIVO -no-snapshot-load

Paquetes utiles:


$ yarn add @react-navigation/native react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view @react-navigation/stack @react-navigation/bottom-tabs @react-navigation/drawer --save
$ yarn add react-native-elements --save
$ yarn add react-native-vector-icons --save
$ yarn add redux-saga --save
$ yarn add redux --save
$ yarn add react-redux --save
$ yarn add final-form react-final-form --save
$ yarn add apisauce --save 
$ yarn add jwt-decode --save
$ yarn add moment --save
$ yarn add prop-types --dev 

JavaScript Cheat Sheet

Verificar si una variable esta inicializada

if (typeof a !== "undefined")

Console

console.log() -> representacion en string de algo
console.dir() -> devuelve un arbol de lo que realmente "es" lo que se pasa como parametro
e.currentTarget -> retorna el elemento original al que se le attach el evento. Esto es por ejemplo cuando dentro de un link ponemos texto y una imagen. Si utilizamos e.target nos va a deolver span o img como elemnto.
e.currentTarget = $(this) de Jquery

Event bubbling

    1. Cuando hacemos click en un elemento HTML. Causamos un evento Click.
    2. Supongamos que el click lo hacemos en un elemento de este tipo
      <a href="#">
          <span>LINK</span>
      </a>
    3. Al hacerle click en realidad estamos haciendo click en el elemento SPAN. Entonces:
      1. Si existe algun listener de un evento click adjuntado a ese elemento se ejecuta.
      2. Luego el navegador sube un nivel, en este caso se encuentra con un tag A. Entonces realiza la misma acción: Si existe algun listener de un evento click adjuntado a ese elemento se ejecuta.
      3. El paso 2 se repite hasta llegar al elemento BODY

e.preventDefault() y e.stopPropagation()

Otra cosa que podemos hacer es modificar el comportamiento del navegador ante un evento

$table.find('.some-class').on('click', function (e) {
    e.preventDefault();  // no realizar el comportamiento por defecto del navegador
    e.stopPropagation(); // no "bubble" el evento a elementos superiores

   //la siguiente linea realiza las mismas acciones que las 2 anteriores
   //return false;
});

e.target()

Es una propiedad del evento que apunta al elemento que fue clickeado.
Es un objeto del tipo DOM Element

e.target() vs e.currentTarget() 

<a class="link" href="#">
    <span><img src="image.png" /> LINK</span>
</a>

Cuando hacemos click en la imagen e.target sera igual al elemento img, y cuando hacemos click en el text link, e.target será igual al elemento span. Pero si utilizamos e.currentTarget nos devolverá el elemento al cual le adjuntamos el evento que esn este caso es el elemento A

$table.find('.some-class').on('click', function (e) {
    //nos muestra el elemento clickleado
    console.log(e.target); 
    //nos muestra el elemento al cual se le adjunto el evento sin importar a cual de sus elementos
    //se les hizo click
    console.log(e.currentTarget); 
});

Node

Instalar nvm

$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.0/install.sh | bash
$ export NVM_DIR="$HOME/.nvm"
$ [ -s "$NVM_DIR/nvm.sh” ] && \. “$NVM_DIR/nvm.sh"
$ [ -s "$NVM_DIR/bash_completion" ] && \.   "$NVM_DIR/bash_completion"
$ nvm --version

//instalar versión
nvm install 8.16.0
//Cambiar versión
$ nvm use 8.16.0

Yarn

Instalar Yarn

//falta


$ yarn init //inicializa un package.json
//Babel convierte solo las nuevas construcciones y sintaxis de los nuevos lenguajes de JS a versiones anteriores
//Si hay nuevas funciones u objetos necesitamos Polifill 
$ yarn add babel-cli --dev
$ yarn add babel-preset-env --dev
$ touch .babelrc 
//agrega lo sigueinte
{
    presets: ["env"]
}
$./node_modules/bin/babel filte/path/to/transpile -o filte/path/transpiled

ES6

Arrow Functions

//before
function(data) {};

//ES6
(data) => {};
data => {};

Si la funcion solo un solo return, se puede usar de las siguientes maneras

() => {
    return 'hola';
};

() => 'hola';


Importante:
Arrow functions anónimas preservan el valor de this, dentro de ellas
En Jquery con Arrow functions
() => {
    $row.fadeOut('normal', () => {
        //Antes
        $(this).fadeOut();
        //ES6
        $row.fadeOut();
    })
}

() => {
    //Antes
    $row.find('div').each(function() {
        $(this).val(2);
    });
    //ES6
    $row.find('div').each((index, element) => {
        $(element).val(2);
    })
}

var, let y const

var: permite reasignar el valor de la variable, tiene scope de funcion, hace variable "hoisting"
let: permite reasignar el valor de la variable, tiene scope de bloque (if por ejemplo), no hace variable "hoisting"
const: no permite reasignar el valor de la variable.
Ejemplo:
const myVar = 1;
myVar = 2; //nos devuelve un error

const myObj = { name: 'Joe'};
myObj.name = 'Doe' //esta permitido

Object literals y Optional Args


cont url = 'http://mydomain.com';
const myObj = { url: url};
const myObj = { url }; //Si la key y el value son iguales se puede usar solo una vez

//Métodos dentro de objetos

const obj = {

    //Antes
    updateRow: function() {
        //update
    }
    //ES6
    updateRow() {
        //update
    }
    //Ademas se pueden establecer parametros opcionales
    updateRow(max = 400) {
        //update
    }
}

Clases

class Helper {
    constructor(maxValue) {
        this.maxValue = maxValue;
        //code
    }

    //La nueva sintaxis get nos permite definir esta especie de propiedad
    // que luego la podemos llamar como Helper._rows
    // tambien existe "set"
    get _rows() {
        //return rows
    }
    //Si esta "propiedad" no usa this adentro, la podemos declarar como estática
    static get _someConst() {
        //return a const value
    }
    //Y la llamamos como Helper._someConst


    static  _utility() {
        //return a calculation
    }
    //Y la llamamos como Helper._utility

    //metodo comun
    getDetails() {
        //code
    }

}

//Herencia

class CustomHelper extends Helper {
    
    //sobreescribir
    getDetails() {
       //new code
    }

    //llamar al metodo de la clase padre
    getParentDetails() {
        super.getDetails()
    }

    //sobre escribir el constructor
    constructor(maxValue, otherValue) {
        super(maxValue);
        this.otherValue = otherValue;
    }


}

const custom = new CustomHelper(100);

Destructuring

const obj = {name: 'Joe', lastName: 'Doe', age: '28'};
//crea tres variables con los valores de obj
let {name, lastName, age} = obj;
//admás se pueden agregar keys que no existan y ponerles valores por defecto
let {name, lastName, age, citizenship = 'spain'} = obj;

//con Arrays: es por posición
const carsArray = ['audi', 'vw', 'ferrari'];
let [car1, car2] = carsArray;

Spread Operator

//con Arrays
const carsArray = ['audi', 'vw', 'ferrari'];

let printCars = (car1, car2, car3) => {
    console.log(car1, car2, car3);
}

//Funciona como si completaran 1 a 1 los argumentos
printCars(...carsArray);

// tambien sirve para array merge
let newCarsArray = ['fiat', 'opel', ...carsArray];

//tambien sirve para copiar un array y agregar nuevos valores solo a la copia 

let copyOfCarsArray = newCarsArray;
copyOfCarsArray.push('porshe');
//esto nos da como resultado que   copyOfCarsArray y newCarsArray poseen porshe
//Por que los arrays se pasan por referencia
let copyOfCarsArray = [...newCarsArray];
copyOfCarsArray.push('porshe');
//esto nos da como resultado que copyOfCarsArray solamente contiene a porshe


Template Strings

//Antes
var nombre = 'Joe';
var mensaje = "Hola mi nombre es: "+ nombre;

//ES6
var nombre = 'Joe';
var mensaje = `Hola mi nombre es: ${nombre}`;

//Además permite tener string con line breaks
var mensaje = 
`Hola mi nombre es: 
Joe Doe
`;

For Loop

//for para colecciones menos objetos
for (let names of data.names) {
}
//for para objetos
for (let names in data.names) {
}

Funciones

// look up the name
// of the item based on the "id" argument.
const { name } = this.props.items.find(i => i.id === id);


this.props.items.map(({ id, name }) => (
    
  • {name}
  • ))}