<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Beatriz Martínez Pérez</title>
    <description>The latest articles on DEV Community by Beatriz Martínez Pérez (@tris460).</description>
    <link>https://dev.to/tris460</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F755871%2F347ee6f5-27de-45f9-9505-55214d4da579.png</url>
      <title>DEV Community: Beatriz Martínez Pérez</title>
      <link>https://dev.to/tris460</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tris460"/>
    <language>en</language>
    <item>
      <title>Notas de React Native</title>
      <dc:creator>Beatriz Martínez Pérez</dc:creator>
      <pubDate>Tue, 19 Sep 2023 18:38:05 +0000</pubDate>
      <link>https://dev.to/tris460/notas-de-react-native-58pi</link>
      <guid>https://dev.to/tris460/notas-de-react-native-58pi</guid>
      <description>&lt;h2&gt;
  
  
  Crear proyecto
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;npx create-react-app miApp&lt;/code&gt; Crear proyecto&lt;br&gt;
&lt;code&gt;npm start&lt;/code&gt; Iniciar el proyecto en el navegador&lt;/p&gt;
&lt;h2&gt;
  
  
  Crear proyecto con Expo Go
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;npx create-expo-app miApp&lt;/code&gt; Comando para crear proyecto&lt;br&gt;
&lt;code&gt;npm start&lt;/code&gt; Generar el QR para iniciar el proyecto, el QR debe leerse desde la app Expo &lt;/p&gt;
&lt;h2&gt;
  
  
  Crear proyecto con React Native CLI
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;npx react-native init miApp&lt;/code&gt; Crear proyecto&lt;br&gt;
&lt;code&gt;npx react-native start&lt;/code&gt; Iniciar Metro para correr el proyecto&lt;br&gt;
&lt;code&gt;npx react-native run-android&lt;/code&gt; Iniciar proyecto en Android&lt;br&gt;
&lt;code&gt;npx react-native run-ios&lt;/code&gt; Iniciar proyecto en iOS&lt;br&gt;
&lt;code&gt;npx react-native log-ios&lt;/code&gt; Acceder a los logs de iOS&lt;br&gt;
&lt;code&gt;npx react-native log-android&lt;/code&gt; Acceder a los logs de Android&lt;/p&gt;
&lt;h3&gt;
  
  
  Comandos útiles
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;adb devices&lt;/code&gt; Para ver los dispositivos conectados en donde podemos trabajar&lt;br&gt;
&lt;code&gt;xcrun simctl list devices&lt;/code&gt; Lista los dispositivos iOS que podemos usar&lt;/p&gt;
&lt;h2&gt;
  
  
  Agregar ESLint
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;npm i eslint --save-dev&lt;/code&gt; Instalar ESLint para ayudarnos con problemas de sintaxis&lt;br&gt;
&lt;code&gt;npm i @react-native-community/eslint-config --save-dev&lt;/code&gt; Instalar ESLint de la comunidad&lt;br&gt;
&lt;code&gt;npm i --save-dev --save-exact prettier&lt;/code&gt; Instalar Prettier para formatear el código, hay que crear .prettierrc.js y ahi agregar las reglas &lt;/p&gt;
&lt;h2&gt;
  
  
  Acceder al menú de debug
&lt;/h2&gt;

&lt;p&gt;En un dispositivo físico se puede agitar el dispositivo para acceder al menú.&lt;br&gt;
Para un emulador en iOS, es con command+d &lt;br&gt;
Para un emulador en Android, es con command+m o control+m&lt;/p&gt;
&lt;h2&gt;
  
  
  Archivos
&lt;/h2&gt;

&lt;p&gt;Para crear archivos, hay que agregar la extensión &lt;code&gt;.tsx&lt;/code&gt;&lt;br&gt;
&lt;code&gt;index.tsx&lt;/code&gt; Es el punto de entrada de la aplicación&lt;br&gt;
&lt;code&gt;tsconfig.json&lt;/code&gt; Están las reglas de como queremos que trabaje TypeScript  &lt;/p&gt;
&lt;h2&gt;
  
  
  Tipado
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;let variable: string;&lt;/code&gt; Agregar una variable con un tipo string&lt;br&gt;
&lt;code&gt;let variable: string = ‘Ejemplo’;&lt;/code&gt; Asignar un valor a la variable&lt;br&gt;
&lt;code&gt;let variable: string | number = 123;&lt;/code&gt; La variable puede tomar un tipo string o un tipo number para su valor&lt;/p&gt;
&lt;h2&gt;
  
  
  Elementos
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;SafeAreaView&lt;/code&gt; Contenedor que inicia la vista bajo la barra de estado&lt;br&gt;
&lt;code&gt;View&lt;/code&gt; Contenedor que no puede ser scrolleado, equivalente al ‘div’ en HTML&lt;br&gt;
&lt;code&gt;Text&lt;/code&gt; Contenedor de texto&lt;br&gt;
&lt;code&gt;StatusBar&lt;/code&gt; Permite hacer modificaciones en el status bar, como cambiar el color de fondo, ocultarlo, estilo, etc.&lt;br&gt;
&lt;code&gt;ActivityIndicator&lt;/code&gt; Permite poner el circulo de ‘cargando’ &lt;code&gt;&amp;lt;ActivityIndicator color=“red” size={20}/&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;code&gt;FlatList&lt;/code&gt; Permite crear listas&lt;/p&gt;
&lt;h2&gt;
  
  
  Estilos
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Estilos en línea
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;View style={{backgroundColor: ‘pink’}}&amp;gt;&lt;/code&gt; Darle al View un background rosa&lt;/p&gt;
&lt;h3&gt;
  
  
  Estilos con condiciones
&lt;/h3&gt;

&lt;p&gt;Para agregar un estilo u otro dependiendo de si una condición se cumple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;style={(condicion) 
? styles.condicionVerdadera
: styles.condicionFalsa}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  StyleSheet
&lt;/h3&gt;

&lt;p&gt;Debe importarse StyleSheet de la API de React Native y crear un objeto antes de exportar el componente, se crea de la siguiente manera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const styles = StyleSheet.create({
    container: {
        backgroundColor: ‘pink’
    }
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;.&lt;br&gt;
&lt;code&gt;&amp;lt;View style={styles.container}&amp;gt;&lt;/code&gt; Para agregarle los estilos a un elemento&lt;br&gt;
&lt;code&gt;&amp;lt;View style={[styles.container, styles.bgBlack]}&amp;gt;&lt;/code&gt; Agregar varios estilos&lt;/p&gt;
&lt;h3&gt;
  
  
  Diseño
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Box object model&lt;/em&gt; Se refiere al alto, ancho, margen, padding y borde&lt;br&gt;
&lt;em&gt;Position&lt;/em&gt; Puede ser absoluta, relativa, etc.&lt;br&gt;
&lt;em&gt;Flex box&lt;/em&gt; Habla de la dirección, ubicación, alineamiento, proporciones, etc.&lt;/p&gt;
&lt;h3&gt;
  
  
  Estilos en otro archivo
&lt;/h3&gt;

&lt;p&gt;Podemos crear nuestro archivo de estilos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { StyleSheet } from "react-native";

const styles = StyleSheet.create({…});

export default styles;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y usarlos normalmente en el archivo donde lo necesitemos, sin olvidar importarlo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const App = () =&amp;gt; {
  return (
    &amp;lt;SafeAreaView style={ styles.container }&amp;gt;…&amp;lt;/SafeAreaView&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Interfaz
&lt;/h3&gt;

&lt;p&gt;Sirven para poner reglas de validación a nuestros objetos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Persona {
nombre: string,
edad: number,
direccion: {
        pais: string,
        estado: string;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La parte de ‘dirección’ puede extraerse en una nueva interfaz.&lt;br&gt;
&lt;code&gt;let persona1: Persona;&lt;/code&gt; Se crea una variable que es del tipo ‘Persona’ de la interfaz creada.&lt;/p&gt;
&lt;h2&gt;
  
  
  Props
&lt;/h2&gt;

&lt;p&gt;Son datos que llegan como parámetros en la función.&lt;br&gt;
&lt;code&gt;const App = (props: Props) =&amp;gt; {…}&lt;/code&gt;&lt;br&gt;
Si de antemano sabemos cuáles serán las propiedades que vamos a recibir, podemos desestructurarlo y elegir solo las propiedades que necesitamos:&lt;br&gt;
&lt;code&gt;const App = ({prop1, prop2}: Props) =&amp;gt; {…}&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Context y estado global de la App
&lt;/h2&gt;

&lt;p&gt;Proporciona una forma de compartir datos entre componentes sin tener que pasar props a través de la jerarquía de componentes manualmente.&lt;br&gt;
El context es como nuestro árbol de componentes.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ejemplo básico&lt;/em&gt;&lt;br&gt;
Aquí vamos a guardar la información del authState en la app para ser accedido por los hijos globalmente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createContext } from "react";

// Define hoy will look like the general data
export interface AuthState {
    isLoggedIn: boolean;
    username?: string;
}

// Define which properties will be shared to the children, in case we don't want to
// add all of AuthState or we want to add more
export interface AuthContextProps {
    authState: AuthState,
    signIn: () =&amp;gt; void;
}

// Initial state
export const authInitialState: AuthState = {
    isLoggedIn: false,
    username: undefined,
}

// Create context, it has the data that will be shared in all children components
export const AuthContext = createContext({} as AuthContextProps);

// State provider component
export const AuthProvider = ({children}: any) =&amp;gt; {
    const [authState, dispatch] = useReducer(authReducer, authInitialState)

    const signIn = () =&amp;gt; {
        dispatch({type: 'signIn'})
    }

    return (
        &amp;lt;AuthContext.Provider value={{
            authState,
            signIn
        }}&amp;gt;
            {children}
        &amp;lt;/AuthContext.Provider&amp;gt;
    );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos envolver App en una función que tenga el AuthProvider para que los elementos hijos tengan acceso a la información del AuthProvider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const App = () =&amp;gt; {
  return (
    &amp;lt;NavigationContainer&amp;gt;
      &amp;lt;AppState&amp;gt;
        &amp;lt;TabsNavigator /&amp;gt;
      &amp;lt;/AppState&amp;gt;
    &amp;lt;/NavigationContainer&amp;gt;
  )
}

const AppState = ({children}: any) =&amp;gt; {
  return (
    &amp;lt;AuthProvider&amp;gt;
      {children}
    &amp;lt;/AuthProvider&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si queremos ejecutar un método de los definidos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const {authState, signIn} = useContext(AuthContext);
&amp;lt;Text&amp;gt;
{JSON.stringify(authState, null, 4)}
&amp;lt;/Text&amp;gt;
{authState.isLoggedIn &amp;amp;&amp;amp; &amp;lt;Button title='Sign in' onPress={signIn} /&amp;gt;}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y hay que manejar el método en el authReducer, el &lt;em&gt;payload&lt;/em&gt; funciona para mandar más información a la acción:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { AuthState } from "./AuthContext";

type AuthAction = 
    { type: 'signIn' } |
    { type: 'logout', payload: string };

// Generates a new state
export const authReducer = (state:AuthState, action: AuthAction):AuthState =&amp;gt; {
    switch (action.type) {
        case 'signIn':
            return {
                ...state,
                isLoggedIn: true,
                username: 'no-username'
            }
        default:
            return state;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Imprimir los datos&lt;/em&gt;&lt;br&gt;
Desde alguno de los componentes hijos podemos usar el hook de useContext:&lt;br&gt;
&lt;code&gt;const {authState} = useContext(AuthContext);&lt;/code&gt;&lt;br&gt;
E imprimir su valor&lt;br&gt;
&lt;code&gt;&amp;lt;Text&amp;gt;{JSON.stringify(authState, null, 4)}&amp;lt;/Text&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Funciones
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;const operacion = () =&amp;gt; {…}&lt;/code&gt; Declarar una función &lt;br&gt;
&lt;code&gt;const operacion = (): number =&amp;gt; {…}&lt;/code&gt; Declarar una función que retorna un dato de tipo number&lt;br&gt;
&lt;code&gt;const operacion = (a: string): number =&amp;gt; {…}&lt;/code&gt; Declarar una función que retorna un dato de tipo number y recibe un parámetro ‘a’ de tipo string&lt;br&gt;
&lt;code&gt;let resultado = operacion(“hola”);&lt;/code&gt; Llamar a la función&lt;/p&gt;
&lt;h2&gt;
  
  
  Carpetas
&lt;/h2&gt;

&lt;p&gt;Hay que crear una carpeta ‘src’ en la raíz del proyecto en donde hay que agregar el código/carpetas que necesitemos. Dentro de esa carpeta, podemos agregar las siguientes carpetas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API: Para almacenar lo referente a peticiones&lt;/li&gt;
&lt;li&gt;Assets: Guarda imágenes, videos, audios, etc.&lt;/li&gt;
&lt;li&gt;Components: Almacenar archivos necesarios para hooks, API, etc.&lt;/li&gt;
&lt;li&gt;Hooks: Aquí se guardan los hooks personalizados.&lt;/li&gt;
&lt;li&gt;Interfaces: Para archivos que muestran el tipado.&lt;/li&gt;
&lt;li&gt;Navigation: Contiene los archivos necesarios para la navegación. - Screens: Para almacenar las vistas del proyecto.&lt;/li&gt;
&lt;li&gt;Theme: Almacena los estilos globales y sus configuraciones.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Componentes
&lt;/h3&gt;

&lt;p&gt;Podemos crear un archivo llamado Navbar.tsx y ahi crear la vista para un navbar, para utilizarlo en el archivo App.tsx hay que agregar su etiqueta e importar el archivo:&lt;br&gt;
&lt;code&gt;&amp;lt;Navbar /&amp;gt;&lt;/code&gt;&lt;br&gt;
A esos componentes podemos enviarles props:&lt;br&gt;
&lt;code&gt;&amp;lt;Navbar title=“Hola” /&amp;gt;&lt;/code&gt;&lt;br&gt;
Pero en el archivo Navbar.tsx tambien hay que definir cuales propiedades van a llegar:&lt;br&gt;
&lt;code&gt;const Navbar = (props: String) =&amp;gt; {…}&lt;/code&gt; o &lt;code&gt;const Navbar = ({title}: String) =&amp;gt; {…}&lt;/code&gt;&lt;br&gt;
&lt;code&gt;const Navbar = ({title?}: String) =&amp;gt; {…}&lt;/code&gt; Para agregar propiedades opcionales se agrega un ‘?’&lt;br&gt;
&lt;code&gt;const Navbar = ({title? = ‘Hola’}: String) =&amp;gt; {…}&lt;/code&gt; Se le da un valor por defecto a la propiedad, para en caso de que no reciba nada&lt;/p&gt;
&lt;h2&gt;
  
  
  Hooks
&lt;/h2&gt;
&lt;h3&gt;
  
  
  useState
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;const [valor, setValor] = useState(0);&lt;/code&gt; Crear una variable de tipo number con valor inicial de 0&lt;br&gt;
&lt;code&gt;setValor(10);&lt;/code&gt; Cambiamos el valor de ‘valor’ a 10&lt;/p&gt;
&lt;h3&gt;
  
  
  useReducer
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;const [state, dispatch] = useReducer[reducer, initialState, init];&lt;/code&gt; Esta es la forma inicial que tiene un useReducer&lt;br&gt;
Si queremos usar este hook para verificar si un usuario inició sesión, podemos agregar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface AuthState { token: string | null };
type AuthAction = { type: ‘logout’} | { type: ‘login’ };
const initialState:AuthState = {token: null};
const authReducer = (state: AuthState, action: AuthAction):AuthState =&amp;gt; {
    if(action.type == ‘logout’) {
        return { token: null }
    } else {
        return { token: ’123abc’ }
    }
}
export const Login = () =&amp;gt; {
    const [state, dispatch] = useReducer(authReducer, initialState];
    useEffect(() =&amp;gt; {
        dispatch({type: ‘logout’});
    }, []); 
    const login = () =&amp;gt; {
        dispatch({type: ‘login’});
    }
    const logout = () =&amp;gt; {
        dispatch({type: ‘logout’});
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El initialState nos dice el estado inicial del valor.&lt;br&gt;
El reducer siempre debe retornar un dato del mismo tipo del initialState, para lo que podemos crear una interfaz con los datos necesarios, además, recibe dos parámetros, un state para el valor del estado y un action que modifica el valor del state.&lt;br&gt;
También tenemos un dispatch, el cual es el método disparador de la acción para cambiar el state, están envueltos en una función, esa función se la podemos agregar a un botón o un elemento donde lo necesitemos.&lt;/p&gt;
&lt;h3&gt;
  
  
  useEffect
&lt;/h3&gt;

&lt;p&gt;Ejecuta el código en el momento en el que se carga el código en nuestra aplicación&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useEffect(() =&amp;gt; {
    console.log(“Hola”);
}, []}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  useNavigation
&lt;/h3&gt;

&lt;p&gt;Sirve para recibir las props en la navegación desde un hook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const navigator = useNavigation()
…
&amp;lt;Button title=‘Ir’ onPress={ () =&amp;gt; navigator.navigate(‘Pagina’)} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  useWindowDimensions
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;const { width, height } = useWindowDimensions();&lt;/code&gt; Permite obtener las dimensiones de la pantalla&lt;/p&gt;

&lt;h3&gt;
  
  
  useColorScheme
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;const colorScheme = useColorScheme();&lt;/code&gt; Devuelve el tema que esta usando el dispositivo (light, dark…)&lt;/p&gt;

&lt;h3&gt;
  
  
  useSafeAreaInsets
&lt;/h3&gt;

&lt;p&gt;Ayuda a trabajar como un SafeAreaView pero más personalizado. Por ejemplo aquí nos ayuda a agregar un margen superior del tamaño necesario para que se vea el contenido. Pero solo en los celulares donde sea necesario.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const insets = useSafeAreaInsets();
return (
    &amp;lt;View style={.{ marginTop: insets.top }.}&amp;gt;
    …
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Hook personalizado
&lt;/h3&gt;

&lt;p&gt;Para crear un archivo para almacenar un hook, hay que agregar ‘use’ al principio &lt;code&gt;useHook.tsx&lt;/code&gt;.&lt;br&gt;
En ese archivo hay que agregar la lógica relacionada al hook, como crear las variables y los métodos, suponiendo que tenemos ‘valor’ y ‘setValor’ en nuestro nuevo hook, hay que retornarlo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const useHook = () =&amp;gt; { 
    const [valor, setValor] = useState(0); 
}
return { valor, setValor };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;.&lt;br&gt;
&lt;code&gt;const { valor, setValor } = useHook();&lt;/code&gt; Importar ese hook en otro archivo para usarlo&lt;/p&gt;
&lt;h4&gt;
  
  
  Recibir parámetros
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const useHook = (valorInicial: number = 10) =&amp;gt; { 
    const [valor, setValor] = useState(0); 
}
return { valor, setValor };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;La función necesita un parámetro ‘valorInicial’ de tipo number el cual no es obligatorio, tomará el valor de 10 si no se le envía ningún parámetro&lt;br&gt;
&lt;code&gt;const { valor, setValor } = useHook(5);&lt;/code&gt; Se le envía un valor como parámetro&lt;/p&gt;
&lt;h2&gt;
  
  
  Peticiones HTTP con Axios
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;npm i axios&lt;/code&gt; Instalar axios&lt;br&gt;
&lt;code&gt;export const api = axios.create({ baseURL: ‘https://url.delapi/api});&lt;/code&gt; Generar la conexión con la API para usarla más adelante&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useEffect(() =&amp;gt; {
api.get(‘/endpoint’)
    .then(res =&amp;gt; {
        console.log(res.data);
    })
    .catch(console.error);
}, []);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ejecutamos la llamada a la API en nuestro archivo, desde el useEffect e imprimimos la información necesaria&lt;br&gt;
&lt;code&gt;api.get&amp;lt;String&amp;gt;(‘/endpoint’)&lt;/code&gt; Podemos decirle el tipo de dato que esperamos, en este caso, un dato de tipo string, o podemos crear una interfaz personalizada&lt;/p&gt;
&lt;h2&gt;
  
  
  Formularios
&lt;/h2&gt;

&lt;p&gt;Podemos tener una variable para el formulario, con useState para guardar el valor cuando cambie.&lt;br&gt;
La función onChange es la que se encarga de guardar el valor en la variable, heredando lo que ya se tenia, para no perder los datos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [formulario, setFormulario] = useState({
    email: ‘ejemplo@test.com’,
    password: ‘123’
});
const onChange = (value: string, campo:string) =&amp;gt; {
    setFormulario({
        …formulario,
        [campo]: value
    });
}
…
&amp;lt;input 
    type=“text” 
    placeholder=“Email”
    value={ formulario.email }
    onChange = { ({ target }) =&amp;gt; onChange(target.value, ‘email’) } /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Navegación
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Stack Navigation
&lt;/h3&gt;

&lt;p&gt;Funciona como una pila, en donde las pantallas se van poniendo una sobre otra, pero las pantallas siempre están activas.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Instalaciones&lt;/em&gt;&lt;br&gt;
&lt;code&gt;npm install @react-navigation/native&lt;/code&gt;&lt;br&gt;
&lt;code&gt;npm install react-native-screens react-native-safe-area-context&lt;/code&gt;&lt;br&gt;
&lt;code&gt;npm install @react-navigation/native-stack&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;En App&lt;/em&gt;&lt;br&gt;
Hay que crear un NavigationContainer con un elemento Stack.Navigator, el cual es personalizado en este ejemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const App = () =&amp;gt; {
  return (
    &amp;lt;NavigationContainer&amp;gt;
        &amp;lt;StackNavigator /&amp;gt;
    &amp;lt;/NavigationContainer&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y en StackNavigator.tsx agregamos las pantallas que van a usarse&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const StackNavigator = () =&amp;gt; {
  return (
    &amp;lt;Stack.Navigator&amp;gt;
      &amp;lt;Stack.Screen name="BoxObjectMrodel" component={BoxObjectModel} /&amp;gt;
      &amp;lt;Stack.Screen name="Calculator" component={Calculator} /&amp;gt;
      &amp;lt;Stack.Screen name="Counter" component={Counter} /&amp;gt;
      &amp;lt;Stack.Screen name="Dimentions" component={Dimentions} /&amp;gt;
      &amp;lt;Stack.Screen name="HelloWorld" component={HelloWorld} /&amp;gt;
      &amp;lt;Stack.Screen name="Position" component={Position} /&amp;gt;
    &amp;lt;/Stack.Navigator&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Agregar un botón para ir a otra pantalla&lt;/em&gt;&lt;br&gt;
Hay que crear una interfaz para obtener las propiedades que pueden enviarse, además de tener las propiedades de la navegación, para poder navegar entre pantallas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import type { NativeStackScreenProps } from '@react-navigation/native-stack';

interface Props extends NativeStackScreenProps&amp;lt;any, any&amp;gt; {}

const MenuStackNavigator = ({navigation}: Props) =&amp;gt; {
  return (
    &amp;lt;View&amp;gt;
        &amp;lt;Button
            title='Ir a’
            onPress={() =&amp;gt; {navigation.navigate(‘Pantalla’)}} /&amp;gt;
    &amp;lt;/View&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Métodos de navigation&lt;/em&gt;&lt;br&gt;
&lt;code&gt;const MiPagina = ({navigation}:any) =&amp;gt; { &amp;lt;Button onPress={() =&amp;gt; navigation.*método*}}&lt;/code&gt;&lt;br&gt;
Una vez que tenemos nuestro botón de ese modo, podemos agregar ciertos métodos:&lt;br&gt;
&lt;code&gt;navigation.pop()&lt;/code&gt; Sirve para volver al elemento anterior en el Stack&lt;br&gt;
&lt;code&gt;navigation.popToTop()&lt;/code&gt; Para ir al primer elemento del stack&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Propiedades del Stack.Navigator&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Stack.Navigator *Propiedades*&amp;gt;
        &amp;lt;Stack.Screen name="Menu" component={MenuStackNavigator} /&amp;gt; 
&amp;lt;/Stack.Navigator&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;.&lt;br&gt;
&lt;code&gt;initialRouteName=“Pagina2”&lt;/code&gt; Define que pantalla será la primera en el stack&lt;br&gt;
&lt;code&gt;screenOptions={{cardStyle: {&lt;/code&gt;&lt;br&gt;
&lt;code&gt;headerShown: false&lt;/code&gt; Mostrar el título de la pantalla en donde se encuentra o no&lt;br&gt;
&lt;code&gt;backgroundColor: ‘white’&lt;/code&gt; Define el color que tendrá la vista (el contenido)&lt;br&gt;
&lt;code&gt;}, headerStyle: {&lt;/code&gt;&lt;br&gt;
&lt;code&gt;elevation: 0&lt;/code&gt; Elimina la línea divisoria entre el título y el contenido (android)&lt;br&gt;
&lt;code&gt;shadowColor: ‘transparent’&lt;/code&gt; Hace la línea divisoria de color transparente&lt;br&gt;
&lt;code&gt;}}}&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Propiedades del Stack.Screen&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Stack.Navigator&amp;gt;
        &amp;lt;Stack.Screen name="Menu" component={MenuStackNavigator} *Propiedades*/&amp;gt;
&amp;lt;/Stack.Navigator&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;.&lt;br&gt;
&lt;code&gt;options={{title:”Titulo 1”}}&lt;/code&gt; Para cambiar el título de la página&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sobreescribir propiedades&lt;/em&gt;&lt;br&gt;
Para sobreescribir el título del componente podemos usar un hook para agregar las propiedades necesarias:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useEffect(() =&amp;gt; {
    navigator.setOptions({ 
        title: ‘Nuevo titulo’
        headerBackTitle: ‘Atras’ //Para el texto iOS que aparece en la flecha de ir atrás
    })
}, [])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Enviar argumentos entre pantallas&lt;/em&gt;&lt;br&gt;
En  el botón hay que agregar los argumentos después de poner a que pantalla queremos ir, puede ser una variable, un objeto, o algún elemento&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Button
    title='Ir a’
    onPress={() =&amp;gt; {navigation.navigate(‘Pantalla’, argumentos)}} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para recibir los parámetros que enviamos podemos imprimirlo en consola:&lt;br&gt;
&lt;code&gt;console.log(JSON.stringify(props, null, 3));&lt;/code&gt;&lt;br&gt;
Las props vienen en los parámetros de la función principal.&lt;br&gt;
La mejor práctica para enviar parámetros se puede encontrar en la página del Navigator.&lt;/p&gt;
&lt;h3&gt;
  
  
  Drawer Navigation
&lt;/h3&gt;

&lt;p&gt;Es la pantalla que se desliza desde un lado de la pantalla, como un menu lateral.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Instalaciones&lt;/em&gt;&lt;br&gt;
&lt;code&gt;npm install @react-navigation/drawer&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ejemplo básico&lt;/em&gt;&lt;br&gt;
El drawer va a generar un menú lateral con los elementos que le agreguemos en Drawer.Screen, aparece al arrastrar el dedo de izquierda a derecha en la pantalla.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createDrawerNavigator } from '@react-navigation/drawer';

const Drawer = createDrawerNavigator();

function MyDrawer() {
  return (
    &amp;lt;Drawer.Navigator&amp;gt;
      &amp;lt;Drawer.Screen name="Feed" component={Feed} /&amp;gt;
      &amp;lt;Drawer.Screen name="Article" component={Article} /&amp;gt;
    &amp;lt;/Drawer.Navigator&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Personalizar el drawer&lt;/em&gt;&lt;br&gt;
&lt;code&gt;&amp;lt;Drawer.Navigator&lt;/code&gt;&lt;br&gt;
&lt;code&gt;drawerPosition=‘right’&lt;/code&gt; El drawer aparece del lado derecho&lt;br&gt;
&lt;code&gt;drawerType=‘front’|’permanent’&lt;/code&gt; Para elegir si queremos que por defecto el menú este oculto o no. Podemos usarlo para agregarlo dependiendo de si el celular esta en modo portrait o landscape agregando una condición ternaria: &lt;code&gt;drawerType={condición}&lt;/code&gt;.&lt;br&gt;
&lt;code&gt;drawerContent={(props) =&amp;gt; &amp;lt;ContenidoInterno /&amp;gt;}&lt;/code&gt; Sirve para poder agregar contenido al drawer, como imágenes, vistas, etc. Hay que agregar los enlaces a otras secciones nuevamente con un TouchableOpacity/Button, etc&lt;br&gt;
&lt;code&gt;&amp;gt;&lt;/code&gt;.&lt;br&gt;
&lt;code&gt;&amp;lt;Drawer.Screen options={{title’:Home’}} … /&amp;gt;&lt;/code&gt; Cambia el nombre que se verá en la pantalla&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Agregar icono de hamburguesa&lt;/em&gt;&lt;br&gt;
El ícono se coloca en las opciones de navegación y se agrega solo cuando inició la aplicación, por lo que podemos agregar un useEffect. Además hay que cambiar el tipo de las Props para poder tener acceso a las propiedades del drawer y de la navegación:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Props extends DrawerScreenProps&amp;lt;any, any&amp;gt;{};
…
useEffect(() =&amp;gt; {
    navigation.setOptions({
        headerLeft: () =&amp;gt; {
            &amp;lt;Button title=“Menu” onPress{() =&amp;gt; navigation.toggleDrawer()} /&amp;gt;
        }
    })
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  BottomTab Navigation
&lt;/h3&gt;

&lt;p&gt;Ofrece un menú inferior que funciona como una lista horizontal de enlaces que van hacia cada pantalla.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Instalaciones&lt;/em&gt;&lt;br&gt;
&lt;code&gt;npm install @react-navigation/bottom-tabs&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ejemplo básico&lt;/em&gt;&lt;br&gt;
El Tab.Navigator contiene todas las pantallas que se van a colocar como Tabs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

const Tab = createBottomTabNavigator();

export const  MyTabs = () =&amp;gt; {
  return (
    &amp;lt;Tab.Navigator&amp;gt;
      &amp;lt;Tab.Screen name="Home" component={HomeScreen} /&amp;gt;
      &amp;lt;Tab.Screen name="Settings" component={SettingsScreen} /&amp;gt;
    &amp;lt;/Tab.Navigator&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Personalizar las tabs&lt;/em&gt;&lt;br&gt;
&lt;code&gt;&amp;lt;Tab.Navigator&lt;/code&gt;.&lt;br&gt;
&lt;code&gt;sceneContainerStyle={{background: ‘white’}}&lt;/code&gt; Pone el color del contenido de la tab en blanco&lt;br&gt;
&lt;code&gt;screenOptions={({route}) =&amp;gt; ({&lt;/code&gt;&lt;br&gt;
&lt;code&gt;tabBarActiveTintcolor: ‘red’,&lt;/code&gt; Cambia el color del texto activo&lt;br&gt;
&lt;code&gt;tabBarStyle: {&lt;/code&gt;.&lt;br&gt;
&lt;code&gt;borderTopColor: ‘red’,&lt;/code&gt; Agrega un borde rojo a todo los tabs&lt;br&gt;
&lt;code&gt;borderTopWidth: 0,&lt;/code&gt; El ancho del borde es 0&lt;br&gt;
&lt;code&gt;elevation: 0&lt;/code&gt; Para que no se generen sombras (android)&lt;br&gt;
&lt;code&gt;},&lt;/code&gt;.&lt;br&gt;
&lt;code&gt;tabBarLabelStyle: {fontSize: 14},&lt;/code&gt; Cambia el tamaño de la fuente de las tabs&lt;br&gt;
&lt;code&gt;tabBarIcon: ({color, focused, size}) =&amp;gt; {&lt;/code&gt; Cambia el icono del tab&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let iconName: string = '';
      switch(route.name) {
          case 'MenuStackNavigator':
             iconName='MSN'
             break;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos usar un switch para ver que texto usar&lt;/p&gt;

&lt;p&gt;&lt;code&gt;return &amp;lt;Text style={{color}}&amp;gt;{iconName}&amp;lt;/Text&amp;gt;&lt;/code&gt; A todos los tabs les pone este texto como ícono y le pone color, el color que recibe como parámetro para que todos se vean igual&lt;br&gt;
&lt;code&gt;}})}&lt;/code&gt;.&lt;br&gt;
&lt;code&gt;&amp;gt;&lt;/code&gt;.&lt;br&gt;
&lt;code&gt;&amp;lt;TabScreen … options={{ tabBaricon: &amp;lt;Icono props /&amp;gt;}}/&amp;gt;&lt;/code&gt; Agregar un ícono, podemos llamar a una etiqueta que reciba datos para cambiar los estilos&lt;/p&gt;
&lt;h3&gt;
  
  
  Material Bottom Tab Navigation
&lt;/h3&gt;

&lt;p&gt;Permite agregar estilos a la navegación que ya teníamos anteriormente en el menú inferior.&lt;br&gt;
 &lt;em&gt;Instalación&lt;/em&gt;&lt;br&gt;
&lt;code&gt;npm install @react-navigation/material-bottom-tabs react-native-paper react-native-vector-icons&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ejemplo básico&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createMaterialBottomTabNavigator } from '@react-navigation/material-bottom-tabs';

const Tab = createMaterialBottomTabNavigator();

const MyTabs = () =&amp;gt; {
  return (
    &amp;lt;Tab.Navigator&amp;gt;
      &amp;lt;Tab.Screen name="Home" component={HomeScreen} /&amp;gt;
      &amp;lt;Tab.Screen name="Settings" component={SettingsScreen} /&amp;gt;
    &amp;lt;/Tab.Navigator&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tenemos las mismas opciones de personalización que con los otros componentes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Material Top Tab Navigation
&lt;/h3&gt;

&lt;p&gt;Es un menú superior que funciona del mismo modo que los componentes anteriores, al permitirte navegar entre diferentes pantallas.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Instalaciones&lt;/em&gt;&lt;br&gt;
&lt;code&gt;npm install @react-navigation/material-top-tabs react-native-tab-view&lt;/code&gt;&lt;br&gt;
&lt;code&gt;npm install react-native-pager-view&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ejemplo básico&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';

const Tab = createMaterialTopTabNavigator();

function MyTabs() {
  return (
    &amp;lt;Tab.Navigator&amp;gt;
      &amp;lt;Tab.Screen name="Home" component={HomeScreen} /&amp;gt;
      &amp;lt;Tab.Screen name="Settings" component={SettingsScreen} /&amp;gt;
    &amp;lt;/Tab.Navigator&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para personalizarlo tenemos las mismas opciones que con las otras navegaciones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ejecutar código dependiendo de la plataforma
&lt;/h2&gt;

&lt;p&gt;Podemos crear una función para Android, otra para iOS dentro de nuestra función principal y validar en qué plataforma se está trabajando para saber qué código hay que retornar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const app = () =&amp;gt; {
    const androidApp = () =&amp;gt; {…}
    const iosApp = () =&amp;gt; {…}
    return (Platform.OS === ‘ios’ ? iosApp() : androidApp();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Agregar iconos
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Instalación&lt;/em&gt;&lt;br&gt;
&lt;code&gt;npm install --save react-native-vector-icons&lt;/code&gt;&lt;br&gt;
Y seguir la guía de instalación en &lt;a href="https://github.com/oblador/react-native-vector-icons"&gt;https://github.com/oblador/react-native-vector-icons&lt;/a&gt;&lt;br&gt;
Hay que instalar los tipos del paquete de iconos que elijamos:&lt;br&gt;
&lt;code&gt;npm i -D @types/react-native-vector-icons&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Agregar icono&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Icon from 'react-native-vector-icons/FontAwesome';
const myIcon = &amp;lt;Icon name="rocket" size={30} color="#900" /&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Animaciones
&lt;/h2&gt;

&lt;p&gt;Creamos una función para que un elemento aparezca en pantalla, para eso necesitamos una referencia de su opacidad:&lt;br&gt;
&lt;code&gt;const opacity = useRef(new Animated.Value(0)).current;&lt;/code&gt;&lt;br&gt;
Para hacer que un elemento aparezca, creamos la función:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const fadeIn = () =&amp;gt; {
        Animated.timing(
            opacity, 
            {toValue: 1, duration: 1000, useNativeDriver: true}
        ).start();
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y agregamos el elemento Animated.View para lo que queremos animar, junto a un botón que inicie la animación:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Animated.View style={{
     backgroundColor: 'black',
     width: 150,
     height: 150,
     borderColor: 'white',
     borderWidth: 10,
     opacity: opacity
}} /&amp;gt;
&amp;lt;Button
     title='Start fadeIn' 
     onPress={() =&amp;gt; fadeIn()} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Verificar el estado de la app
&lt;/h2&gt;

&lt;p&gt;Con el AppState de react-native podemos monitorear cuando nuestra aplicación esta activa, inactiva o si está en segundo plano.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useEffect(() =&amp;gt; {
      AppState.addEventListener('change', state =&amp;gt; {
        console.log(state);
      })
    }, [])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Cambiar icono, nombre, splash screen de la app
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Cambiar el nombre
&lt;/h3&gt;

&lt;p&gt;Hay que ir a android/app/src/main/res/strings.xml y ahi actualizar el texto de la aplicación que viene por defecto&lt;/p&gt;

&lt;h3&gt;
  
  
  Cambiar ícono
&lt;/h3&gt;

&lt;p&gt;Hay que crear un ícono (hay generadores de iconos en internet de donde podemos crear uno y descargarlo (descargar todas sus medidas disponibles).&lt;br&gt;
Hay que tener images cuadradas y redondas. y almacenarlas en android/app/src/main/res/mipmap… cada una en su respectiva carpeta, y en cada una hay que tener una versión circular y una cuadrada del ícono.&lt;br&gt;
En el AndroidManifest (android/app/src/main/AndroidManifest.xml) es en donde se definen los nombres de las imagenes que se toman por defecto.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round”
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Splash creen
&lt;/h3&gt;

&lt;p&gt;Se puede seguir el tutorial de este enlace: &lt;a href="https://github.com/crazycodeboy/react-native-splash-screen"&gt;https://github.com/crazycodeboy/react-native-splash-screen&lt;/a&gt;&lt;br&gt;
Hacer las instalaciones, modificaciones de los archivos nativos, crear los archivos launch_screen.xml y generar el diseño para el splash creen, después importar el paquete en la pantalla donde lo queremos mostrar y configurar el splash screen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generar APK
&lt;/h2&gt;

&lt;p&gt;Debe seguirse la guía de la documentación oficial: &lt;a href="https://reactnative.dev/docs/signed-apk-android"&gt;https://reactnative.dev/docs/signed-apk-android&lt;/a&gt;&lt;br&gt;
 ## Subir a Google Play el app&lt;br&gt;
Se sube desde: &lt;a href="https://play.google.com/console/about/"&gt;https://play.google.com/console/about/&lt;/a&gt;&lt;br&gt;
Debe hacerse un pago y llenar los datos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Otros
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;Text style={styles.text}&amp;gt;Texto: {“\n”}Ejemplo&amp;lt;/Text&amp;gt;&lt;/code&gt; Para dar un salto de línea en el mismo Text&lt;br&gt;
&lt;code&gt;const { width, height } = Dimensions.get('window');&lt;/code&gt; Obtener el ancho y alto de la pantalla pero al girar el dispositivo, las medidas se mantienen cuando deberían cambiar, es mejor usar el hook ‘useWindowDimentions’&lt;br&gt;
&lt;code&gt;&amp;lt;MiElemento opcionBool /&amp;gt;&lt;/code&gt; Si necesitamos enviarle props booleanas no es necesario inicializarla en true, el hecho de agregar la propiedad hace que se retorne un true&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;p&gt;React Native con TypeScript: &lt;a href="https://create-react-app.dev/docs/adding-typescript/"&gt;https://create-react-app.dev/docs/adding-typescript/&lt;/a&gt;&lt;br&gt;
React Navigation: &lt;a href="https://reactnavigation.org/docs/getting-started/"&gt;https://reactnavigation.org/docs/getting-started/&lt;/a&gt;&lt;br&gt;
React Drawer Navigation: &lt;a href="https://reactnavigation.org/docs/drawer-based-navigation/"&gt;https://reactnavigation.org/docs/drawer-based-navigation/&lt;/a&gt;&lt;br&gt;
Bottom Tab Navigator: &lt;a href="https://reactnavigation.org/docs/bottom-tab-navigator/"&gt;https://reactnavigation.org/docs/bottom-tab-navigator/&lt;/a&gt;&lt;br&gt;
Material Top Tab Navigator: &lt;a href="https://reactnavigation.org/docs/material-top-tab-navigator/"&gt;https://reactnavigation.org/docs/material-top-tab-navigator/&lt;/a&gt;&lt;br&gt;
React Native APIs: &lt;a href="https://reactnative.dev/docs/accessibilityinfo"&gt;https://reactnative.dev/docs/accessibilityinfo&lt;/a&gt;&lt;br&gt;
Colores en iOS: &lt;a href="https://developer.apple.com/design/human-interface-guidelines/color%E2%80%A8Colores"&gt;https://developer.apple.com/design/human-interface-guidelines/color Colores&lt;/a&gt; en Android: &lt;a href="https://m2.material.io/design/color/color-usage.html"&gt;https://m2.material.io/design/color/color-usage.html&lt;/a&gt;&lt;br&gt;
React Native con TypeScript: &lt;a href="https://create-react-app.dev/docs/adding-typescript/"&gt;https://create-react-app.dev/docs/adding-typescript/&lt;/a&gt;&lt;br&gt;
Iconos: &lt;a href="https://github.com/oblador/react-native-vector-icons"&gt;https://github.com/oblador/react-native-vector-icons&lt;/a&gt;&lt;br&gt;
Lista de iconos disponibles: &lt;a href="https://ionic.io/ionicons"&gt;https://ionic.io/ionicons&lt;/a&gt;&lt;br&gt;
Carrusel: &lt;a href="https://github.com/meliorence/react-native-snap-carousel"&gt;https://github.com/meliorence/react-native-snap-carousel&lt;/a&gt;&lt;br&gt;
Gradientes: &lt;a href="https://github.com/react-native-linear-gradient/react-native-linear-gradient"&gt;https://github.com/react-native-linear-gradient/react-native-linear-gradient&lt;/a&gt;&lt;br&gt;
Analizar colores de imagenes: &lt;a href="https://github.com/osamaqarem/react-native-image-colors"&gt;https://github.com/osamaqarem/react-native-image-colors&lt;/a&gt;&lt;br&gt;
Temas: &lt;a href="https://reactnavigation.org/docs/themes/"&gt;https://reactnavigation.org/docs/themes/&lt;/a&gt;&lt;br&gt;
Permisos: &lt;a href="https://www.npmjs.com/package/react-native-permissions"&gt;https://www.npmjs.com/package/react-native-permissions&lt;/a&gt;&lt;br&gt;
Extensiones: &lt;a href="https://reactnative.dev/docs/app-extensions"&gt;https://reactnative.dev/docs/app-extensions&lt;/a&gt;&lt;br&gt;
Ejercicios: &lt;a href="https://www.tutorialspoint.com/react_native/index.htm"&gt;https://www.tutorialspoint.com/react_native/index.htm&lt;/a&gt;&lt;br&gt;
Libro con ejercicios: &lt;a href="https://books.goalkicker.com/ReactNativeBook/"&gt;https://books.goalkicker.com/ReactNativeBook/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>cheatsheet</category>
      <category>typescript</category>
      <category>mobile</category>
    </item>
    <item>
      <title>Comandos para la terminal</title>
      <dc:creator>Beatriz Martínez Pérez</dc:creator>
      <pubDate>Sat, 22 Apr 2023 20:26:49 +0000</pubDate>
      <link>https://dev.to/tris460/comandos-para-la-terminal-3257</link>
      <guid>https://dev.to/tris460/comandos-para-la-terminal-3257</guid>
      <description>&lt;h2&gt;
  
  
  ¿Qué es la terminal?
&lt;/h2&gt;

&lt;p&gt;Interfaz gráfica que simula una línea de comandos, es decir, una shell. La terminal es una ventana en donde está el prompt. La línea de comandos (shell) es quien toma los comandos y los manda al sistema operativo para hacer algo.&lt;/p&gt;

&lt;p&gt;Tipos de shells:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Boune shell&lt;/li&gt;
&lt;li&gt;Bash shell&lt;/li&gt;
&lt;li&gt;PowerShell&lt;/li&gt;
&lt;li&gt;Z Shell&lt;/li&gt;
&lt;li&gt;C Shell&lt;/li&gt;
&lt;li&gt;Korn Shell&lt;/li&gt;
&lt;li&gt;Fish Shell&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En la terminal encontrarás lo siguiente:&lt;br&gt;
nombreDeUsuario@nombreDelEquipo:directorio$&lt;/p&gt;

&lt;p&gt;Podemos usar estos atajos: &lt;br&gt;
&lt;code&gt;Ctrl + C&lt;/code&gt; Mata el proceso actual&lt;br&gt;
&lt;code&gt;Ctrl + L&lt;/code&gt; Limpia la pantalla&lt;/p&gt;

&lt;h3&gt;
  
  
  Definiciones
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Comando&lt;/strong&gt; Un comando puede ser un programa ejecutable, un comando de utilidad de la shell, una función del shell o un alias.&lt;br&gt;
&lt;strong&gt;Wildcards&lt;/strong&gt; Son caracteres especiales (?, *) que permiten encontrar patrones o realizar búsquedas en al menos dos niveles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comandos básicos
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;clear&lt;/code&gt; Limpia la pantalla (Ctrl + L)&lt;br&gt;
&lt;code&gt;cd ruta&lt;/code&gt; Cambia el directorio actual&lt;br&gt;
&lt;code&gt;cd ..&lt;/code&gt; Regresa al directorio anterior&lt;br&gt;
&lt;code&gt;pwd&lt;/code&gt; Devuelve la ruta en donde estamos&lt;br&gt;
&lt;code&gt;echo "Hello world"&lt;/code&gt; Imprime el texto que escribamos&lt;br&gt;
&lt;code&gt;cat archivo.extension&lt;/code&gt; Muestra el contenido del archivo&lt;br&gt;
&lt;code&gt;cat archivo1.ext archivo2.ext&lt;/code&gt; Muestra el contenido de ambos archivos&lt;br&gt;
&lt;code&gt;file archivo.md&lt;/code&gt; Devuelve la información del archivo&lt;br&gt;
&lt;code&gt;tree&lt;/code&gt; Despliega todos los archivos existentes&lt;br&gt;
&lt;code&gt;tree -L 2&lt;/code&gt; Limita los niveles de ramas a 2&lt;br&gt;
&lt;code&gt;type comando&lt;/code&gt; Devuelve el tipo de comando que es&lt;br&gt;
&lt;code&gt;alias nombre="comando"&lt;/code&gt; Crea un alias para un comando, son temporales si no se guardan&lt;br&gt;
&lt;code&gt;help comando&lt;/code&gt; Muestra la ayuda para ese comando&lt;br&gt;
&lt;code&gt;comando --help&lt;/code&gt; Muestra la ayuda para ese comando&lt;br&gt;
&lt;code&gt;man comando&lt;/code&gt; Muestra el manual de usuario del comando especificado&lt;br&gt;
&lt;code&gt;info comando&lt;/code&gt; Muestra la información del comando (es más legible que 'man')&lt;br&gt;
&lt;code&gt;whatis comando&lt;/code&gt; Devuelve la descripción de qué hace un comando, no funciona con todos los comandos&lt;br&gt;
&lt;code&gt;whoami&lt;/code&gt; Muestra quien somos en el sistema operativo&lt;br&gt;
&lt;code&gt;id&lt;/code&gt; Da información sobre el usuario&lt;br&gt;
&lt;code&gt;cal&lt;/code&gt; Muestra un calendario&lt;br&gt;
&lt;code&gt;date&lt;/code&gt; Muestra la fecha y hora del sistema operativo&lt;br&gt;
&lt;code&gt;printenv&lt;/code&gt; Muestra todas las variables de entorno configuradas&lt;br&gt;
&lt;code&gt;echo $HOME&lt;/code&gt; Imprime el valor de esa variable de entorno &lt;br&gt;
&lt;code&gt;jobs&lt;/code&gt; Muestra los procesos que están en segundo plano y su número de trabajo&lt;br&gt;
&lt;code&gt;fg 1&lt;/code&gt; Saca el proceso que tenga el número de trabajo '1' del segundo plano y lo trae a primer plano (la terminal)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;su root&lt;/code&gt; Cambia al usuario root&lt;br&gt;
&lt;code&gt;sudo comando&lt;/code&gt; Ejecuta el comando con el usuario root&lt;br&gt;
&lt;code&gt;passwd&lt;/code&gt; Para cambiar la contraseña &lt;/p&gt;

&lt;p&gt;&lt;code&gt;mkdir Directorio&lt;/code&gt; Crea un directorio (pueden crearse varios al mismo tiempo)&lt;br&gt;
&lt;code&gt;touch archivo.extension&lt;/code&gt; Crea un archivo (pueden crearse varios al mismo tiempo)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cp archivoACopiar Ruta/NombreNuevoArchivo&lt;/code&gt; Copia un archivo&lt;br&gt;
&lt;code&gt;mv archivoAMover Ruta&lt;/code&gt; Mueve el archivo a la ruta donde especifiquemos&lt;br&gt;
&lt;code&gt;mv nombreAnterior nombreNuevo&lt;/code&gt; Cambia el nombre del archivo/directorio&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rm archivo&lt;/code&gt; Elimina un archivo&lt;br&gt;
&lt;code&gt;rm -i archivo&lt;/code&gt; Elimina un archivo, pero antes solicita confirmación (i = interactive)&lt;br&gt;
&lt;code&gt;rm -r directorio&lt;/code&gt; Elimina un directorio (r = recursive)&lt;br&gt;
&lt;code&gt;rm -f archivo&lt;/code&gt; Fuerza la eliminación de un archivo/directorio&lt;/p&gt;

&lt;p&gt;&lt;code&gt;head archivo&lt;/code&gt; Muestra las primeras 10 líneas del archivo&lt;br&gt;
&lt;code&gt;head archivo -n 15&lt;/code&gt; Muestra las primeras 15 líneas del archivo&lt;br&gt;
&lt;code&gt;tail archivo&lt;/code&gt; Muestra las últimas 10 líneas del archivo&lt;br&gt;
&lt;code&gt;tail archivo -n 12&lt;/code&gt; Muestra las últimas 12 líneas del archivo&lt;br&gt;
&lt;code&gt;less archivo&lt;/code&gt; Muestra el archivo completo, interactivo. Con &lt;code&gt;/&lt;/code&gt; podemos buscar palabras y con &lt;code&gt;q&lt;/code&gt; salimos.&lt;br&gt;
&lt;code&gt;open archivo&lt;/code&gt; Abre un archivo como normalmente se haría (MAC)&lt;br&gt;
&lt;code&gt;xdg-open archivo&lt;/code&gt; Abre el archivo (Linux)&lt;/p&gt;

&lt;h3&gt;
  
  
  Archivos
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;ls&lt;/code&gt; Lista los archivos y directorios del directorio donde te encuentras&lt;br&gt;
&lt;code&gt;ls -d&lt;/code&gt; Lista los directorios&lt;br&gt;
&lt;code&gt;ls -l&lt;/code&gt; Lista los archivos con detalles (l = long)&lt;br&gt;
&lt;code&gt;ls -lh&lt;/code&gt; Lista los archivos mostrando los detalles más legibles (h = human)&lt;br&gt;
&lt;code&gt;ls -la&lt;/code&gt; Lista los archivos ocultos&lt;br&gt;
&lt;code&gt;ls -ls&lt;/code&gt; Lista los archivos por tamaño (s = size)&lt;br&gt;
&lt;code&gt;ls -lr&lt;/code&gt; Lista los archivos de Z-A (r = reverse)&lt;br&gt;
&lt;code&gt;ls -s ruta nombreLink&lt;/code&gt; Crea un link simbólico, para no escribir toda la ruta, solo escribimos su nombre&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wildcards&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;ls *.txt&lt;/code&gt; Lista todos los archivos que terminen en '.txt'&lt;br&gt;
&lt;code&gt;ls a*&lt;/code&gt; Lista todo lo que inicie con 'a'&lt;br&gt;
&lt;code&gt;ls a?&lt;/code&gt; Lista todo lo que inicie con 'a' y tenga solo un carácter después (pueden agregarse múltiples '?')&lt;br&gt;
&lt;code&gt;ls [[:uppercase:]]*&lt;/code&gt; Lista lo que inicie con mayúscula y tenga más caracteres después&lt;br&gt;
&lt;code&gt;ls -d [[:uppercase:]]*&lt;/code&gt; Lista los directorios que inicien con mayúscula y tengan más caracteres después&lt;br&gt;
&lt;code&gt;ls [[:lower:]]*&lt;/code&gt; Lista lo que inicie con minúscula&lt;br&gt;
&lt;code&gt;ls [ad]*&lt;/code&gt; Lista lo que inicie con 'a' o 'd' y tenga más caracteres después&lt;/p&gt;

&lt;h3&gt;
  
  
  Comandos de búsqueda
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;which comando&lt;/code&gt; Ayuda a encontrar la ruta de los binarios del comando&lt;br&gt;
&lt;code&gt;find ruta -name archivo&lt;/code&gt; Busca 'archivo' y empieza a buscar en 'ruta'&lt;br&gt;
&lt;code&gt;find ruta -type d -name directorio&lt;/code&gt; Busca un directorio (d) de nombre 'directorio', para buscar archivo es &lt;code&gt;-type f&lt;/code&gt;&lt;br&gt;
&lt;code&gt;find ruta -size 20M&lt;/code&gt; Busca los archivos que pesen 20MB&lt;/p&gt;

&lt;p&gt;&lt;code&gt;grep palabra archivo.ext&lt;/code&gt; Busca 'palabra' dentro de 'archivo.ext'&lt;br&gt;
&lt;code&gt;grep -i palabra archivo.ext&lt;/code&gt; Busca 'palabra' en 'archivo.ext' ignorando mayúsculas/minúsculas&lt;br&gt;
&lt;code&gt;grep -c palabra archivo.ext&lt;/code&gt; Cuenta las veces que aparece 'palabra'&lt;br&gt;
&lt;code&gt;grep -vi palabra archivo.ext&lt;/code&gt; Muestra lo que no tenga 'palabra'&lt;br&gt;
&lt;code&gt;wc archivo.ext&lt;/code&gt; Muestra cuántas líneas tiene el archivo, cuántos caracteres, número de bits y el nombre del archivo&lt;br&gt;
&lt;code&gt;wc -l archivo&lt;/code&gt; Devuelve el número de líneas del archivo&lt;br&gt;
&lt;code&gt;wc -w archivo&lt;/code&gt; Devuelve el número de palabras del archivo&lt;br&gt;
&lt;code&gt;wc -c archivo&lt;/code&gt; Devuelve el número de bits del archivo&lt;/p&gt;

&lt;h3&gt;
  
  
  Utilidades de red
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;ifconfig&lt;/code&gt; Muestra información de red&lt;br&gt;
&lt;code&gt;ping url&lt;/code&gt; Conecta con la URL proporcionada para ver si está activa&lt;br&gt;
&lt;code&gt;curl url&lt;/code&gt; Trae un archivo desde esa URL, por ejemplo, el HTML&lt;br&gt;
&lt;code&gt;wget url&lt;/code&gt; Parecido a 'curl', descarga algo desde la red&lt;br&gt;
&lt;code&gt;traceroute url&lt;/code&gt; Muestra si hay algún servidor fallando para llegar de nuestra computadora a la URL&lt;br&gt;
&lt;code&gt;netstat -i&lt;/code&gt; Muestra los dispositivos e información de la red&lt;/p&gt;

&lt;h3&gt;
  
  
  Comprimir archivos
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;tar -cvf comprimido.tar aComprimir&lt;/code&gt; Comprime el archivo en .tar, mostrando que va comprimiendo (c = compress, v = verbose, f = file)&lt;br&gt;
&lt;code&gt;tar -cvfz comprimido.tar.gz comprimido.tar&lt;/code&gt; Comprime el archivo en gzip (z = gzip)&lt;br&gt;
&lt;code&gt;tar -vfzx comprimido.tar.gz&lt;/code&gt; Descomprime el archivo&lt;br&gt;
&lt;code&gt;zip -r comprimido.zip comprimir&lt;/code&gt; Comprime en .zip&lt;br&gt;
&lt;code&gt;unzip comprimido.zip&lt;/code&gt; Descomprime el archivo zip&lt;/p&gt;

&lt;h3&gt;
  
  
  Manejo de procesos
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;ps&lt;/code&gt; Muestra los procesos/comandos que se estén ejecutando actualmente con su PID&lt;br&gt;
&lt;code&gt;kill PID&lt;/code&gt; Mata el proceso dado el PID&lt;br&gt;
&lt;code&gt;top&lt;/code&gt; Muestra los procesos que usan más recursos&lt;/p&gt;

&lt;h3&gt;
  
  
  Editor de texto en la terminal
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;sudo apt install vim&lt;/code&gt; Instala vim (vi es el editor antiguo, vim = vi moderno)&lt;br&gt;
&lt;code&gt;vim&lt;/code&gt; Abre una pantalla para crear archivos de texto&lt;br&gt;
&lt;code&gt;vim archivo.ext&lt;/code&gt; Crea 'archivo.ext' para editarlo&lt;/p&gt;

&lt;h3&gt;
  
  
  Pipe: Combinar comandos
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;ls -lh | less&lt;/code&gt; Lista los archivos de forma interactiva&lt;br&gt;
&lt;code&gt;ls -lh | less | tee archivo.ext&lt;/code&gt; 'Tee' hace que el resultado se guarde en 'archivo.ext'. El resultado es la lista de archivos de forma interactiva.&lt;br&gt;
&lt;code&gt;ls -lh  | tee archivo.ext | less&lt;/code&gt; Primero guarda la salida y luego muestra la salida con 'less'&lt;br&gt;
&lt;code&gt;ls directorio | sort&lt;/code&gt; Muestra la salida de A-Z&lt;/p&gt;

&lt;h3&gt;
  
  
  Encadenar comandos
&lt;/h3&gt;

&lt;p&gt;Ejecutar comandos de modo síncrono (uno detrás de otro)&lt;br&gt;
&lt;code&gt;ls; mkdir directorio; cal&lt;/code&gt; Separa comandos con ';', primero lista los archivos, después crea un directorio y finalmente muestra un calendario.&lt;br&gt;
Ejecutar comandos de modo asíncrono (por cada comando se abre otra shell en segundo plano)&lt;br&gt;
&lt;code&gt;ls &amp;amp; date &amp;amp; cal&lt;/code&gt; Muestra en que número de proceso (PID) se ejecutó el comando y muestra las salidas&lt;/p&gt;

&lt;h3&gt;
  
  
  Ejecutar comandos de manera condicional
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;AND&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;mkdir directorio &amp;amp;&amp;amp; cd directorio&lt;/code&gt; Si se puede, crea 'directorio' y va a la carpeta&lt;br&gt;
&lt;strong&gt;OR&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;cd ruta || touch archivo&lt;/code&gt; Si 'ruta' existe, accede, si no existe, crea 'archivo'&lt;br&gt;
&lt;code&gt;cd ruta || touch archivo || echo "Hola"&lt;/code&gt; Si 'ruta' existe, accede, sino, crea 'archivo', si el archivo se crea, el proceso finaliza, sino, ejecuta el 'echo'&lt;/p&gt;

&lt;h3&gt;
  
  
  Permisos
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Estructura de un permiso
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;-rw-r--r--&lt;/code&gt; &lt;br&gt;
El primer caracter es el tipo de archivo (-)&lt;br&gt;
Los siguientes 3 caracteres son los permisos para el usuario (rw-)&lt;br&gt;
Los siguientes 3 caracteres son los permisos para grupos (r--)&lt;br&gt;
Los siguientes 3 caracteres son los permisos para otros (r--)&lt;/p&gt;

&lt;h4&gt;
  
  
  Tipo de archivo
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;-&lt;/code&gt; Un archivo normal&lt;br&gt;
&lt;code&gt;d&lt;/code&gt; Directorios&lt;br&gt;
&lt;code&gt;l&lt;/code&gt; Un link simbólico (acceso directo desde la terminal)&lt;br&gt;
&lt;code&gt;d&lt;/code&gt; Un archivo de bloque especial (guarda información de un dispositivo (USB, HDD) normalmente)&lt;/p&gt;

&lt;h4&gt;
  
  
  Tipo de modo
&lt;/h4&gt;

&lt;p&gt;Permisos:&lt;br&gt;
r = read = Permiso de ver el contenido del archivo&lt;br&gt;
w = write = Permiso de editar el contenido del archivo&lt;br&gt;
x = execute = Permiso para ejecutar el contenido del archivo&lt;br&gt;
Los permisos activos tienen '1'&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Modo dueño&lt;/strong&gt; (quien creó el archivo, tiene archivo de leer, escribir y ejecutar)&lt;br&gt;
r w x&lt;br&gt;
1 1 1&lt;br&gt;
&lt;strong&gt;Modo grupo&lt;/strong&gt; (para archivos compartidos, tiene permiso de leer y ejecutar)&lt;br&gt;
r w x&lt;br&gt;
1 0 1&lt;br&gt;
&lt;strong&gt;Modo world&lt;/strong&gt; (otros, tiene permiso de leer y ejecutar)&lt;br&gt;
r w x&lt;br&gt;
1 0 1&lt;br&gt;
&lt;strong&gt;Modo simbólico&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;u&lt;/code&gt; Permiso solo para el usuario&lt;br&gt;
&lt;code&gt;g&lt;/code&gt; Permiso solo para el grupo&lt;br&gt;
&lt;code&gt;o&lt;/code&gt; Permiso solo para otros (ni usuario ni grupo)&lt;br&gt;
&lt;code&gt;a&lt;/code&gt; permiso para todos&lt;/p&gt;

&lt;h4&gt;
  
  
  Modificar permisos en la terminal
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Definir permisos en diferentes modos&lt;/strong&gt;&lt;br&gt;
r w x&lt;br&gt;
1 1 1     - Boleano&lt;br&gt;
4 2 1     - Binario&lt;br&gt;
4 2 1 = 7 - Octal&lt;/p&gt;

&lt;p&gt;Es decir, para asignar todos el permiso 'rx' sería:&lt;br&gt;
r w x&lt;br&gt;
1 0 1     - Boleano&lt;br&gt;
4 0 1     - Binario&lt;br&gt;
4 0 1 = 5 - Octal&lt;/p&gt;

&lt;p&gt;Para asignar todos el permiso 'r' sería:&lt;br&gt;
r w x&lt;br&gt;
1 0 0     - Boleano&lt;br&gt;
4 0 0     - Binario&lt;br&gt;
4 0 0 = 4 - Octal&lt;/p&gt;

&lt;p&gt;&lt;code&gt;chmod 755 archivo&lt;/code&gt; Cambia los permisos de 'archivo', está en octal, Da todos los permisos al usuario, y 'rx' para grupos y otros.&lt;br&gt;
&lt;code&gt;chmod u-r archivo&lt;/code&gt; Quita el permiso de lectura (r) al usuario (u)&lt;br&gt;
&lt;code&gt;chmod u+r archivo&lt;/code&gt; Da el permiso de lectura (r) al usuario (u)&lt;br&gt;
&lt;code&gt;chmod u-x,go=w archivo&lt;/code&gt; Quita al usuario el permiso de ejecución (x) y a grupo y otros (go) solo les da el permiso de escritura (w)&lt;/p&gt;

&lt;h2&gt;
  
  
  Juego
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;sudo apt install cowsay&lt;/code&gt; Muestra un mensaje con una vaca&lt;br&gt;
&lt;code&gt;sudo apt install lolcat&lt;/code&gt; Cambia de color cualquier texto&lt;br&gt;
&lt;code&gt;cowsay -l&lt;/code&gt; Muestra los dibujos disponibles, se debe poner -f&lt;br&gt;
&lt;code&gt;cowsay "Hola"&lt;/code&gt; Devuelve una vaca diciendo 'Hola'&lt;br&gt;
&lt;code&gt;lolcat "Hola"&lt;/code&gt; Muestra 'Hola' de diferente color&lt;br&gt;
`&lt;code&gt;cowsay "Hola" | lolcat&lt;/code&gt; Devuelve una vaca colorida diciendo 'Hola'&lt;br&gt;
&lt;code&gt;cowsay -f dragon-and-cow "Hola" | lolcat&lt;/code&gt; Devuelve un dragón con una vaca,  coloridos, diciendo 'Hola'&lt;br&gt;
&lt;code&gt;cowsay -f dragon-and-cow "Hola" | lolcat -F 12 -d 5 -a&lt;/code&gt; Anima el resultado&lt;/p&gt;

</description>
      <category>terminal</category>
      <category>beginners</category>
      <category>cheatsheet</category>
    </item>
    <item>
      <title>Comandos básicos de MySQL</title>
      <dc:creator>Beatriz Martínez Pérez</dc:creator>
      <pubDate>Thu, 13 Apr 2023 19:47:06 +0000</pubDate>
      <link>https://dev.to/tris460/comandos-basicos-de-mysql-53im</link>
      <guid>https://dev.to/tris460/comandos-basicos-de-mysql-53im</guid>
      <description>&lt;h2&gt;
  
  
  ¿Qué es una base de datos?
&lt;/h2&gt;

&lt;p&gt;Una base de datos es un conjunto perteneciente al mismo contexto y almacenados sistemáticamente. Se compone por tablas, columnas, filas y campos.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Una tabla es una estructura que organiza datos en una matriz.&lt;/li&gt;
&lt;li&gt;Una columna es un conjunto de datos organizados verticalmente.&lt;/li&gt;
&lt;li&gt;Una fila o registro es un conjunto de datos organizados horizontalmente.&lt;/li&gt;
&lt;li&gt;Un campo es un dato individual.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Las bases de datos tienen ciertas restricciones, por ejemplo, la clave primaria, clave foránea, restricción de nulos, entre otros.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clave primaria: Campo que se utiliza para identificar de forma única cada fila de la tabla, no puede tener valores duplicados ni nulos, y sirve para establecer relaciones.&lt;/li&gt;
&lt;li&gt;Clave foránea o externa: Es un campo o conjunto de campos en una tabla que hace referencia a la clave primaria de otra tabla.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Se necesitan querys para ejecutar los comandos en la base de datos.&lt;br&gt;
Para crear archivos que ejecuten comandos SQL, el archivo debe llevar la extensión '.sql'.&lt;/p&gt;

&lt;p&gt;Nota: Las mayúsculas no son necesarias para ejecutar los comandos, pero nos ayudan a entender mejor la sintaxis.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comandos básicos
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;help&lt;/code&gt; Mostrar la ayuda&lt;br&gt;
&lt;code&gt;status&lt;/code&gt; Muestra información sobre MySQL&lt;br&gt;
&lt;code&gt;create database miBD&lt;/code&gt; Crea la base de datos 'miBD'&lt;br&gt;
&lt;code&gt;create database info exists miBD&lt;/code&gt; Crea la base de datos 'miBD' solo en caso de que no exista&lt;br&gt;
&lt;code&gt;show databases;&lt;/code&gt; Muestra las bases de datos existentes&lt;br&gt;
&lt;code&gt;use miBD;&lt;/code&gt; Usar la base de datos 'miBD' para ejecutar comandos&lt;br&gt;
&lt;code&gt;drop database miBD;&lt;/code&gt; Elimina la base de datos 'miBD'&lt;br&gt;
&lt;code&gt;show tables;&lt;/code&gt; Muestra las tablas de la base de datos elegida&lt;br&gt;
&lt;code&gt;create table miTabla(campo1 int(3), campo2 varchar(10));&lt;/code&gt; Crea una tabla con los campos 'campo1' y 'campo2', de tipo Integer y Varchar&lt;br&gt;
&lt;code&gt;desc miTabla;&lt;/code&gt; Muestra información de cómo está conformada la tabla 'miTabla'&lt;br&gt;
&lt;code&gt;drop table miTabla;&lt;/code&gt; Elimina la tabla 'miTabla'&lt;/p&gt;

&lt;h3&gt;
  
  
  Modificar tablas
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;ALTER TABLE miTabla RENAME TO nuevoNombre&lt;/code&gt; Cambia el nombre de la tabla 'miTabla' a 'nuevoNombre'&lt;br&gt;
&lt;code&gt;ALTER TABLE miTabla CHANGE columna1 apellidos varchar (10) null;&lt;/code&gt; Cambia el nombre de la columna 'columna1' a 'apellidos' y cambia las restricciones &lt;br&gt;
&lt;code&gt;ALTER TABLE miTabla MODIFY apellidos char(10) not null;&lt;/code&gt; Cambia las restricciones de una columna (apellidos) sin cambiar el nombre&lt;br&gt;
&lt;code&gt;ALTER TABLE miTabla ADD columna3 varchar(9) null;&lt;/code&gt; Agrega la columna 'columna3' a la tabla 'miTabla'&lt;br&gt;
&lt;code&gt;ALTER TABLE miTabla ADD CONSTRAINT uq_email UNIQUE(email);&lt;/code&gt; Añade la condición de que el campo 'email' sea único&lt;br&gt;
&lt;code&gt;ALTER TABLE miTabla DROP columna3;&lt;/code&gt; Elimina la columna 'columna3' sin importar que tenga datos&lt;/p&gt;

&lt;h3&gt;
  
  
  Lenguaje de manipulación de datos
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;SELECT&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;SELECT * FROM miTabla;&lt;/code&gt; Devuelve todos los registros de la tabla 'miTabla'&lt;br&gt;
&lt;code&gt;SELECT * FROM miTabla \G&lt;/code&gt; Devuelve todos los registros de la tabla, con otro formato&lt;br&gt;
&lt;code&gt;SELECT col1, col2 FROM miTabla&lt;/code&gt; Devuelve todos los registros de las columnas seleccionadas (col1, col2)&lt;br&gt;
&lt;code&gt;SELECT email, (1+1) FROM miTabla&lt;/code&gt; Devuelve los campos de la columna 'email' y agrega una columna con el resultado de la operación '1+1'&lt;br&gt;
&lt;code&gt;SELECT email, (1+1) AS suma FROM miTabla&lt;/code&gt; Se le agrega un alias a la columna con la operación, para que su nombre aparezca como 'suma', en vez de '1+1'&lt;br&gt;
&lt;code&gt;SELECT id, name FROM miTabla ORDER BY id DESC;&lt;/code&gt; Devuelve los 'id' y 'name' de 'miTabla' ordenándolos de forma descendente por 'id'&lt;br&gt;
&lt;code&gt;SELECT id, name FROM miTabla ORDER BY id ASC;&lt;/code&gt; Devuelve los 'id' y 'name' de 'miTabla' ordenándolos de forma ascendente por 'id'&lt;br&gt;
&lt;code&gt;SELECT * FROM miTabla WHERE email="email@email.com";&lt;/code&gt; Devuelve solo los registros que cumplan con la condición que se encuentra después del 'WHERE'&lt;br&gt;
&lt;code&gt;SELECT * FROM miTabla WHERE YEAR(fecha)=2019;&lt;/code&gt; Devuelve los registros que tengan el año '2019' en la columna 'fecha'&lt;br&gt;
&lt;code&gt;SELECT * FROM usuarios WHERE YEAR(fecha)!=2019;&lt;/code&gt; Devuelve los registros que no tengan el año '2019' en la columna 'fecha'&lt;br&gt;
&lt;code&gt;SELECT * FROM miTabla WHERE YEAR(fecha)=2019 OR ISNULL(fecha);&lt;/code&gt; Devuelve los registros que no tengan el año '2019' en la columna 'fecha' o que su valor sea nulo&lt;br&gt;
&lt;code&gt;SELECT * FROM miTabla WHERE apellido LIKE '%a%';&lt;/code&gt; Devuelve todos los registros que tengan una 'a' en cualquier lugar del campo en la columna 'apellido'&lt;br&gt;
&lt;code&gt;SELECT * FROM miTabla WHERE apellido LIKE '%a%' AND pass='123';&lt;/code&gt; Devuelve todos los registros que tengan una 'a' en cualquier lugar del campo en la columna 'apellido' y que el valor de 'pass' sea '123'&lt;br&gt;
&lt;code&gt;SELECT * FROM miTabla WHERE (YEAR(fecha)%2 = 0);&lt;/code&gt; Devuelve los registros que tengan un año par en la columna 'fecha'&lt;br&gt;
&lt;code&gt;SELECT * FROM miTabla LIMIT 2;&lt;/code&gt; Limita la cantidad de registros obtenidos a 2&lt;br&gt;
&lt;code&gt;SELECT * FROM miTabla LIMIT 2,4;&lt;/code&gt; Muestra solo los registros que estén entre el rango 2 a 4&lt;br&gt;
&lt;code&gt;SELECT UPPER(nombre) FROM miTabla;&lt;/code&gt; Devuelve los registros con la columna 'nombre' en mayúsculas&lt;br&gt;
&lt;code&gt;SELECT LOWER(nombre) FROM miTabla;&lt;/code&gt; Devuelve los registros con la columna 'nombre' en minúsculas&lt;br&gt;
&lt;code&gt;SELECT nombre FROM miTabla WHERE LENGTH(nombre)&amp;gt;5;&lt;/code&gt; Devuelve los registros cuyo valor en la columna 'nombre' supere los 5 caracteres&lt;br&gt;
&lt;code&gt;SELECT (id+1) FROM miTabla;&lt;/code&gt; Devuelve los ID de la tabla, sumandos 1&lt;br&gt;
&lt;code&gt;SELECT ABS(numero) FROM miTabla;&lt;/code&gt; Devuelve el valor absoluto de cada valor en la columna 'numero'&lt;br&gt;
&lt;code&gt;SELECT CEIL(decimal) from miTabla;&lt;/code&gt; Devuelve el valor de la columna 'decimal' redondeado al número siguiente&lt;br&gt;
&lt;code&gt;SELECT FLOOR(decimal) from miTabla;&lt;/code&gt; Devuelve el valor de la columna 'decimal' redondeando al número anterior&lt;br&gt;
&lt;code&gt;SELECT ROUND(decimal, 2) from miTabla;&lt;/code&gt; Redondea el valer de la columna 'decimal' y muestra 2 decimales después del punto&lt;br&gt;
&lt;code&gt;SELECT PI() from miTabla;&lt;/code&gt; Imprime el valor de PI&lt;br&gt;
&lt;code&gt;SELECT SQRT(numero) from miTabla;&lt;/code&gt; Devuelve la raíz cuadrada de la columna 'numero'&lt;br&gt;
&lt;code&gt;SELECT RAND() FROM miTabla;&lt;/code&gt; Devuelve números aleatorios&lt;br&gt;
&lt;code&gt;SELECT TRUNCATE(decimal, 2) FROM miTabla;&lt;/code&gt; Solo muestra 2 decimales después del punto en la columna 'decimal'&lt;br&gt;
&lt;code&gt;SELECT CONCAT(col1, ':)') FROM miTabla;&lt;/code&gt; Concatena el valor de la columna 'col1' agregándole ':)'&lt;br&gt;
&lt;code&gt;SELECT LENGHT(col1) FROM miTabla;&lt;/code&gt; Devuelve la cantidad de caracteres que contiene cada campo en la columna 'col1'&lt;br&gt;
&lt;code&gt;SELECT TRIM(col1) FROM miTabla;&lt;/code&gt; Elimina los espacios de antes y después de los campos en la columna 'col1'&lt;br&gt;
&lt;code&gt;SELECT CURDATE() FROM miTabla;&lt;/code&gt; Imprime la fecha actual&lt;br&gt;
&lt;code&gt;SELECT CURTIME() FROM miTabla;&lt;/code&gt; Imprime la hora actual&lt;br&gt;
&lt;code&gt;SELECT DATEDIFF(fecha, fecha2) FROM miTabla;&lt;/code&gt; Imprime la diferencia en días entre las columnas 'fecha' y 'fecha2'&lt;br&gt;
&lt;code&gt;SELECT DAYNAME(fecha) FROM miTabla;&lt;/code&gt; Devuelve el día de la semana a la que corresponde la fecha &lt;br&gt;
&lt;code&gt;SELECT DAYOFMONTH(fecha) FROM miTabla;&lt;/code&gt; Devuelve el número del día de la fecha en la columna 'fecha'}&lt;br&gt;
&lt;code&gt;SELECT SYSTEMDATE() FROM miTabla;&lt;/code&gt; Devuelve la fecha y hora actual del sistema operativo donde se está ejecutando la consulta&lt;br&gt;
&lt;code&gt;SELECT DAYOFWEEK(fecha) FROM miTabla;&lt;/code&gt; Devuelve el número del día respecto a la semana&lt;br&gt;
&lt;code&gt;SELECT DAYOFYEAR(fecha) FROM miTabla;&lt;/code&gt; Devuelve qué número del día del año tiene la fecha de la columna 'fecha'&lt;br&gt;
&lt;code&gt;SELECT MONTH(fecha) FROM miTabla;&lt;/code&gt; Devuelve el mes que tiene la fecha&lt;br&gt;
&lt;code&gt;SELECT YEAR(fecha) FROM miTabla;&lt;/code&gt; Devuelve el año que tiene la fecha&lt;br&gt;
&lt;code&gt;SELECT DAY(fecha) FROM miTabla;&lt;/code&gt; Devuelve el día que tiene la fecha&lt;br&gt;
&lt;code&gt;SELECT HOUR(fecha) FROM miTabla;&lt;/code&gt; Devuelve la hora que tiene la fecha&lt;br&gt;
&lt;code&gt;SELECT MINUTE(fecha) FROM miTabla;&lt;/code&gt; Devuelve el minuto que tiene la fecha&lt;br&gt;
&lt;code&gt;SELECT DATE_FORMAT(fecha, '%d-%m-%Y') FROM miTabla;&lt;/code&gt; Muestra las fechas de la columna 'fecha' con el formato indicado en el segundo parámetro&lt;br&gt;
&lt;code&gt;SELECT ISNULL(name) FROM miTabla;&lt;/code&gt; verifica si el campo es nulo, si lo es, devuelve 0, sino, 1&lt;br&gt;
&lt;code&gt;SELECT STRCMP(name, apellido) FROM miTabla;&lt;/code&gt; Compara los valores de las columnas 'name' y 'apellido' y devuelve 0 si son iguales o 1 si son diferentes&lt;br&gt;
&lt;code&gt;SELECT VERSION FROM miTabla;&lt;/code&gt; Devuelve la versión SQL que se está usando&lt;br&gt;
&lt;code&gt;SELECT USER() FROM miTabla;&lt;/code&gt; Devuelve el usuario actual&lt;br&gt;
&lt;code&gt;SELECT USER() DISTINCT FROM miTabla;&lt;/code&gt; Devuelve solo valores sin repetirse&lt;br&gt;
&lt;code&gt;SELECT DISTINCT DATABASE() FROM miTabla;&lt;/code&gt; Devuelve el nombre de la base de datos&lt;br&gt;
&lt;code&gt;SELECT IFNULL(name, '---') FROM miTabla;&lt;/code&gt; Verifica si los campos de la columna 'name' son nulos, si lo son, pone '---' como valor&lt;br&gt;
&lt;code&gt;SELECT col1 FROM miTabla GROUP BY col2;&lt;/code&gt; Agrupa los resultados de 'col1', agrupándolos por el valor en 'col2'&lt;br&gt;
&lt;code&gt;SELECT COUNT(col1) FROM miTabla GROUP BY col2;&lt;/code&gt; Agrupa los resultados y muestra cuántos resultados hay&lt;br&gt;
&lt;code&gt;SELECT COUNT(col1) FROM miTabla GROUP BY col2 HAVING COUNT(col1) &amp;gt; 4;&lt;/code&gt; Agrupa y cuenta los resultados y solo muestra los que cumplan co la condición de ser mayores a 4&lt;br&gt;
&lt;code&gt;SELECT AVG(numero) FROM miTabla;&lt;/code&gt; Devuelve el promedio de los valores de la columna 'numero'&lt;br&gt;
&lt;code&gt;SELECT MAX(numero) FROM miTabla;&lt;/code&gt; Devuelve el registro con el mayor valor en la columna 'numero'&lt;br&gt;
&lt;code&gt;SELECT MIN(numero) FROM miTabla;&lt;/code&gt; Devuelve el registro con el menor valor en la columna 'numero'&lt;br&gt;
&lt;code&gt;SELECT SUM(col1) FROM miTabla;&lt;/code&gt; Devuelve la suma de todos los valores en la columna 'col1'&lt;br&gt;
&lt;code&gt;SELECT * FROM tabla1 WHERE id IN (SELECT tabla1_id FROM tabla2);&lt;/code&gt; Devuelve los registros de 'tabla1' cuyo ID se encuentre en la columna 'tabla1_id' de 'tabla2'&lt;br&gt;
&lt;code&gt;SELECT * FROM tabla1 WHERE id NOT IN (SELECT tabla1_id FROM tabla2);&lt;/code&gt; Devuelve los registros de 'tabla1' cuyo ID no se encuentre en la columna 'tabla1_id' de 'tabla2'&lt;br&gt;
&lt;code&gt;SELECT users.name, data.title FROM users, data;&lt;/code&gt; Devuelve las columnas especificadas desde dos tablas&lt;br&gt;
&lt;code&gt;SELECT u.name, d.title FROM users u, data d;&lt;/code&gt; Le da un alias a los nombres de las tablas&lt;br&gt;
&lt;code&gt;SELECT u.name, d.title FROM users u, data d WHERE u.data_id = d.id AND d.user_id = u.id;&lt;/code&gt; Devuelve los registros cuando los ID's coincidan para evitar tener muchos campos&lt;br&gt;
&lt;code&gt;SELECT u.id FROM users u INNER JOIN data d ON u.data_id = d.id GROUP BY u.name;&lt;/code&gt; Muestra los registros donde se relacionen los usuarios y datos, agrupándolos, si no hay relación, no se muestran&lt;br&gt;
&lt;code&gt;SELECT d.id FROM data d LEFT JOIN users u ON d.user_id = u.id GROUP BY d.title;&lt;/code&gt; Muestra todos los registros de la primer tabla  (data)que no tengan relación con la segunda tabla (users)&lt;br&gt;
&lt;code&gt;SELECT d.id FROM data d RIGHT JOIN users u ON d.user_id = u.id GROUP BY d.title;&lt;/code&gt; Muestra los registros de la segunda tabla (users) que no tengan relación con la primer tabla (data)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;INSERT&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;INSERT INTO miTabla VALUES(null, 'test', 19, '2019-10-29');&lt;/code&gt; Guarda un nuevo registro en la tabla 'miTabla', no se pueden omitir campos&lt;br&gt;
&lt;code&gt;INSERT INTO miTabla(email, pass) VALUES('test@test.com', '123');&lt;/code&gt; Guardar un nuevo registro con solo las columnas seleccionadas (email, pass)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;UPDATE miTabla SET fecha=CURDATE();&lt;/code&gt; Actualiza la columna 'fecha' y le agrega el valor de la fecha actual&lt;br&gt;
&lt;code&gt;UPDATE miTabla SET fecha=CURDATE() WHERE id=3;&lt;/code&gt; Actualiza la columna 'fecha' con el valor de la fecha actual del registro con ID '3'&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DELETE&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;DELETE FROM miTabla WHERE id='1';&lt;/code&gt; Elimina un registro de la tabla 'miTabla' que tenga ID '1'&lt;/p&gt;

&lt;h3&gt;
  
  
  Vistas
&lt;/h3&gt;

&lt;p&gt;Guardar un query para verlo más rápido y usar menos recursos. La información siempre esta actualizada. Para ver las vistas existentes, se ejecuta &lt;code&gt;show tables;&lt;/code&gt;&lt;br&gt;
&lt;code&gt;CREATE VIEW miVista AS SELECT * FROM miTabla;&lt;/code&gt; Crea una vista, dandole un alias al query 'select' para no tener que escribir todo&lt;br&gt;
&lt;code&gt;SELECT * FROM miVista;&lt;/code&gt; Muestra el contenido de la vista&lt;br&gt;
&lt;code&gt;DROP VIEW miVista;&lt;/code&gt; Elimina la vista creada&lt;/p&gt;

&lt;h3&gt;
  
  
  Restricciones al crear una tabla
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;CREATE TABLE miTabla(&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;id int(10) auto_increment not null,&lt;/code&gt;&lt;br&gt;
&lt;code&gt;edad int(2) not null,&lt;/code&gt;&lt;br&gt;
&lt;code&gt;nombre varchar(20) default "usuario",&lt;/code&gt;&lt;br&gt;
&lt;code&gt;apellido varchar(15) null,&lt;/code&gt;&lt;br&gt;
&lt;code&gt;CONSTRAINT pk_miTabla PRIMARY KEY(id),&lt;/code&gt;&lt;br&gt;
&lt;code&gt;CONSTRAINT fk_miTabla_tabla2 FOREIGN KEY (usuario_id) REFERENCES usuario(id),&lt;/code&gt;&lt;br&gt;
&lt;code&gt;CONSTRAINT fk_miTabla_tabla2 FOREIGN KEY (usuario_id) REFERENCES usuario(id) ON DELETE CASCADE,&lt;/code&gt;&lt;br&gt;
&lt;code&gt;CONSTRAINT fk_miTabla_tabla2 FOREIGN KEY (usuario_id) REFERENCES usuario(id) ON DELETE SET NULL,&lt;/code&gt;&lt;br&gt;
&lt;code&gt;CONSTRAINT fk_miTabla_tabla2 FOREIGN KEY (usuario_id) REFERENCES usuario(id) ON DELETE SET DEFAULT,&lt;/code&gt;&lt;br&gt;
&lt;code&gt;CONSTRAINT fk_miTabla_tabla2 FOREIGN KEY (usuario_id) REFERENCES usuario(id) ON DELETE NO ACTION,&lt;/code&gt;&lt;br&gt;
&lt;code&gt;CONSTRAINT fk_miTabla_tabla2 FOREIGN KEY (usuario_id) REFERENCES usuario(id) ON UPDATE CASCADE,&lt;/code&gt;&lt;br&gt;
&lt;code&gt;CONSTRAINT fk_miTabla_jefe FOREIGN KEY(jefe) REFERENCES miTabla(id);&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;)ENGINE=InnoDb;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;auto_increment: Auto-incrementa el valor automáticamente&lt;br&gt;
null: Permite nulos&lt;br&gt;
not null: No permite nulos&lt;br&gt;
default 'valor': Da un valor por defecto por si el usuario no lo pone&lt;br&gt;
pk_miTabla PRIMARY KEY(col): Define 'col' como llave primaria con nombre 'pk_miTabla'&lt;br&gt;
fk_miTabla_tabla2 FOREIGN KEY(col) REFERENCES usuario(id): Define 'col' como llave foránea con referencia a la columna 'id' de la tabla 'usuario'&lt;br&gt;
ON DELETE CASCADE: Cuando se borre el registro, también sus datos relacionados se borran&lt;br&gt;
ON DELETE SET NULL: Cuando se borre el registro, ponerlo como nulo&lt;br&gt;
ON DELETE SET DEFAULT: Cuando se borre el registro, poner el valor default&lt;br&gt;
ON DELETE NO ACTION: Cuando se borre el registro, no hacer nada&lt;br&gt;
ON UPDATE CASCADE: Cuando se actualice un registro, el registro relacionado también se actualiza&lt;br&gt;
fk_miTabla_jefe FOREIGN KEY(jefe) REFERENCES miTabla(id): Hace referencia a la misma tabla pero a otro registro&lt;br&gt;
ENGINE=InnoDb: Indica el motor/forma de almacenar los datos, para mantener la integridad, aumentar rendimiento, etc. Otro: MyISAM permite tener mas velocidad pero no mantiene la integridad&lt;/p&gt;

&lt;h2&gt;
  
  
  Notas
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Operadores de comparación para WHERE
&lt;/h3&gt;

&lt;p&gt;Igual: =&lt;br&gt;
Diferente: !=&lt;br&gt;
Menor: &amp;lt;&lt;br&gt;
Mayor: &amp;gt;&lt;br&gt;
Menor o igual: &amp;lt;=&lt;br&gt;
Mayor o igual: &amp;gt;=&lt;br&gt;
Entre: BETWEEN a AND b&lt;br&gt;
En: IN&lt;br&gt;
Nulo: IS NULL&lt;br&gt;
No nulo: IS NOT NULL&lt;br&gt;
Es como: LIKE&lt;br&gt;
No es como: NOT LIKE&lt;/p&gt;

&lt;h3&gt;
  
  
  Operadores lógicos
&lt;/h3&gt;

&lt;p&gt;O: OR&lt;br&gt;
Y: AND&lt;br&gt;
No: NOT&lt;/p&gt;

&lt;h3&gt;
  
  
  Tipos de datos en SQL
&lt;/h3&gt;

&lt;p&gt;int(10) - Entero de 10 caracteres máximos&lt;br&gt;
float(10,3) - Decimal de 10 caracteres máximos y con máximo 3 decimales&lt;br&gt;
varchar(90) - String (puede contener hasta 255 caracteres)&lt;br&gt;
char(1) - String de un solo carácter&lt;br&gt;
mediumtext - String de 65000 caracteres&lt;br&gt;
longtext - String de 4 millones de caracteres&lt;br&gt;
date - Fecha&lt;br&gt;
time - Hora&lt;br&gt;
timestamp - Hora en formato UTF&lt;/p&gt;

</description>
      <category>mysql</category>
      <category>database</category>
      <category>sql</category>
      <category>terminal</category>
    </item>
    <item>
      <title>Administración de bases de datos con SQL Server</title>
      <dc:creator>Beatriz Martínez Pérez</dc:creator>
      <pubDate>Mon, 23 Jan 2023 20:30:21 +0000</pubDate>
      <link>https://dev.to/tris460/administracion-de-bases-de-datos-con-sql-server-1fm1</link>
      <guid>https://dev.to/tris460/administracion-de-bases-de-datos-con-sql-server-1fm1</guid>
      <description>&lt;h1&gt;
  
  
  Copias de seguridad y restauración
&lt;/h1&gt;

&lt;p&gt;Una copia de seguridad es un mecanismo de protección ante cualquier inconveniente (fallo de lectura de un disco, problema con el hardware del servidor, accesos indeseados al sistema), ya que puede ser necesario recuperar los datos en la última situación estable del servidor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tipos de copias de seguridad
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Respaldo completo
&lt;/h3&gt;

&lt;p&gt;Hace una copia de seguridad de todo. Almacena todos los objetos de la BD: tablas, procedimientos, funciones, vistas...&lt;br&gt;
También crea una copia del registro de transacciones, para que la BD se pueda recuperar.&lt;br&gt;
Para realizar una copia de seguridad completa, se necesita ejecutar el comando:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;BACKUP DATABASE DBDemoATC&lt;br&gt;
To DISK='f:\PowerSQL\DBDemoATC.BAK'&lt;br&gt;
WITH FORMAT,&lt;br&gt;
MEDIANAME = 'Native_SQLServerBackup',&lt;br&gt;
NAME = 'Full-SQLShackDemoATC backup';&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Para realizar la copia de seguridad en varios archivos:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;BACKUP DATABASE SQLShackDemoATC TO&lt;br&gt;
DISK = 'f:\PowerSQL\SQLShackDemoATC_1.BAK’,&lt;br&gt;
DISK = 'f:\PowerSQL\SQLShackDemoATC_2.BAK’,&lt;br&gt;
DISK = 'f:\PowerSQL\SQLShackDemoATC_3.BAK’,&lt;br&gt;
DISK = 'f:\PowerSQL\SQLShackDemoATC_4.BAK'&lt;br&gt;
WITH INIT, NAME = 'FULL SQLShackDemoATC backup’, STATS 5&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Respaldo diferencial
&lt;/h3&gt;

&lt;p&gt;Un respaldo diferencial copia solamente los cambios realizados desde la última copia de seguridad completa, como no copia todos los archivos, suele ejecutarse más rápido.&lt;br&gt;
Las copias de seguridad diferenciales ahorran espacio de almacenamiento y el tiempo para realizar copias de seguridad,  a medida que los datos cambian con el tiempo, el tamaño e la copia de seguridad diferencial también aumenta.&lt;br&gt;
Para ejecutar un respaldo diferencial, se ejecuta:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;BACKUP DATABASE DBDemoATC&lt;br&gt;
To DISK='f:\PowerSQL\DBDemoATC.BAK'&lt;br&gt;
WITH DIFFERENTIAL,&lt;br&gt;
MEDIANAME = 'Native_SQLServerBackup',&lt;br&gt;
NAME = 'Full-SQLShackDemoATC backup';&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Respaldo del registro de transacciones
&lt;/h3&gt;

&lt;p&gt;Realiza una copia de seguridad de los registros de transacciones, como su nombre lo indica, este tipo de copia solo es posible con modelos de recuperación de registro completo o masivo.&lt;br&gt;
Esta copia contiene todos los registros de transacciones que no se incluyeron en la última copia de seguridad del registro de transacciones.&lt;br&gt;
Para crear una copia de seguridad de este tipo, se ejecuta:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;BACKUP LOG SQLShackDemoATC&lt;br&gt;
To DISK='f:\PowerSQL\SQLShackDemoATC_Log.trn'&lt;br&gt;
WITH&lt;br&gt;
MEDIANAME = 'Native_SQLServerLogBackup',&lt;br&gt;
NAME = 'Log-SQLShackDemoATC backup';&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Copia de seguridad de la copia de seguridad de archivos
&lt;/h3&gt;

&lt;p&gt;Las copias de seguridad de archivos de grupos de archivos de solo lectura se pueden combinar con copias de seguridad parciales. Las copias de seguridad parciales incluyen todos los grupos de archivos de lectura / escritura y, opcionalmente, uno o más grupos de archivos de solo lectura.&lt;br&gt;
Para crear una copia de seguridad de archivo, se ejecuta:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;CREATE DATABASE SQLShackFileBackup ON PRIMARY&lt;br&gt;
( NAME = N'SQLShackFileBackup_1',&lt;br&gt;
FILENAME = N'f:\PowerSQL\SQLShackFileBackup_1.mdf' ,&lt;br&gt;
SIZE = 5000KB , FILEGROWTH = 1024KB ),&lt;br&gt;
FILEGROUP [Secondary]&lt;br&gt;
( NAME = N'SQLShackFileBackup_2',&lt;br&gt;
FILENAME = N'f:\PowerSQL\SQLShackFileBackup_2.ndf' ,&lt;br&gt;
SIZE = 5000KB , FILEGROWTH = 1024KB )&lt;br&gt;
LOG ON&lt;br&gt;
( NAME = N'SQLShackFileBackup_Log',&lt;br&gt;
FILENAME = N'f:\PowerSQL\SQLShackFileBackup_Log.ldf' ,&lt;br&gt;
SIZE = 1024KB , FILEGROWTH = 10%)&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Para ejecutar una copia de seguridad a nivel de archivo de los archivos, se ejecuta:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;BACKUP DATABASE SQLShackFileBackup&lt;br&gt;
FILE = 'SQLShackFileBackup_1',&lt;br&gt;
FILE = 'SQLShackFileBackup_2'&lt;br&gt;
TO DISK = 'f:\PowerSQL\SQLShackGroupfiles.bak';&lt;br&gt;
GO&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Copia de seguridad espejo
&lt;/h3&gt;

&lt;p&gt;Son copias idénticas en la misma copia de seguridad, usualmente se almacenan en diferentes dispositivos de copia de seguridad, incrementando la fiabilidad y reduciendo la probabilidad de pérdida de datos.&lt;br&gt;
Como desventaja se tiene que cada copia de seguridad necesita espacio adicional de disco.&lt;br&gt;
Para crear una copia de seguridad de la BD de este tipo, se usa el comando:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;BACKUP DATABASE AdventureWorks2014&lt;br&gt;
TO DISK = 'C:\Mirror_01\AdventureWorks2014_Mirror_01.bak'&lt;br&gt;
MIRROR TO DISK = 'D:\Mirror_02\AdventureWorks2014_Mirror_02.bak'&lt;br&gt;
MIRROR TO DISK = 'E:\Mirror_03\AdventureWorks2014_Mirror_03.bak'&lt;br&gt;
WITH FORMAT&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Para hacer una copia de seguridad de los logs:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;BACKUP LOG AdventureWorks2014&lt;br&gt;
TO DISK = 'C:\Mirror_01\AdventureWorks2014_Mirror_01.bak'&lt;br&gt;
MIRROR TO DISK = 'D:\Mirror_02\AdventureWorks2014_Mirror_02.bak'&lt;br&gt;
MIRROR TO DISK = 'E:\Mirror_03\AdventureWorks2014_Mirror_03.bak&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h1&gt;
  
  
  Automatización de tareas
&lt;/h1&gt;

&lt;p&gt;Los Administradores de Bases de Datos (DBA) tienen que aprender a automatizar tareas repetitivas, de tal forma que dichas tareas sean ejecutadas de forma consistente.&lt;br&gt;
Las ventajas de la automatización son:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reducir la carga de trabajo&lt;/li&gt;
&lt;li&gt;Reducir el riesgo de olvidar tareas&lt;/li&gt;
&lt;li&gt;Reducir los errores humanos&lt;/li&gt;
&lt;li&gt;Manejo de proactividad en la administración&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Las herramientas nativas disponibles para realizar la automatización de tareas en SQL Server son el Asistente y Diseñador de Planes de Mantenimiento y el Servicio de Agentes para la creación de objetos (jobs, alertas, notificaciones y operadores).&lt;/p&gt;

&lt;p&gt;Las operaciones de mantenimiento de rutina que se tienen que ejecutar en el servidor de BD son:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Asegurar la integridad de las BD con el comando &lt;code&gt;DBCC CHECKDB&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Actualización de estadísticas de los objetos, tablas e índices&lt;/li&gt;
&lt;li&gt;Reducción del tamaño de la BD&lt;/li&gt;
&lt;li&gt;Respaldos de BD&lt;/li&gt;
&lt;li&gt;Tareas de limpieza de datos&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;
  
  
  Administración de seguridad
&lt;/h1&gt;

&lt;p&gt;Conceptos básicos de seguridad:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Login de SQL Server&lt;/li&gt;
&lt;li&gt;Usuario de la BD&lt;/li&gt;
&lt;li&gt;Rol de la BD&lt;/li&gt;
&lt;li&gt;Rol de una aplicación&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Inicios de sesión (Login)
&lt;/h2&gt;

&lt;p&gt;Es la habilidad de usar una instancia del Servidor SQL, está asociado con un usuario de Windows o SQL. Son autenticados con SQL Server, por lo que son los accesos al servidor, pero no pueden acceder a las BD u otros objetos (para eso necesita usuarios).&lt;br&gt;
Un inicio de sesión (o identidad) e también una cuenta que un usuario puede usar para acceder al servidor SQL. Los inicios de sesión se adjuntan a los usuarios mediante el identificador de seguridad (SID).&lt;br&gt;
para crear un login, se ejecuta: &lt;code&gt;CREATE LOGIN &amp;lt;loginname&amp;gt; WITH PASSWORD = '&amp;lt;Password&amp;gt;';&lt;/code&gt;&lt;br&gt;
Si queremos crear un inicio de sesión con una contraseña que debe cambiarse, se ejecuta:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;CREATE LOGIN &amp;lt;loginname&amp;gt; WITH PASSWORD = '&amp;lt;Password&amp;gt;'&lt;br&gt;
MUST_CHANGE, CHECK_EXPIRATION = ON;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Para eliminar un inicio de sesión que se usa para conectarse a una instancia de SQL Server&lt;br&gt;
&lt;code&gt;DROP LOGIN login_name;&lt;/code&gt;&lt;br&gt;
Para modificar un inicio de sesión, se puede usar ALTER LOGIN, para cambiar una contraseña, deshabilitar/habilitar/bloquear/renombrar un inicio de sesión, etc. Su sintaxis es:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ALTER LOGIN login_name&lt;br&gt;
{ ENABLE | DISABLE&lt;br&gt;
| WITH PASSWORD = 'password' | hashed_password HASHED&lt;br&gt;
[ OLD_PASSWORD = 'old_password' ]&lt;br&gt;
| MUST_CHANGE&lt;br&gt;
| UNLOCK&lt;br&gt;
| DEFAULT_DATABASE = database_name&lt;br&gt;
| DEFAULT_LANGUAGE = language_name&lt;br&gt;
| NAME = new_login_name&lt;br&gt;
| CHECK_EXPIRATION = { ON | OFF }&lt;br&gt;
| CHECK_POLICY = { ON | OFF }&lt;br&gt;
| CREDENTIAL = credential_name&lt;br&gt;
| NO CREDENTIAL&lt;br&gt;
| ADD CREDENTIAL new_credential_name&lt;br&gt;
| DROP CREDENTIAL credential_name };&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Sus parámetros son:&lt;br&gt;
login_name: El nombre de inicio de sesión asignado actualmente al inicio de sesión.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ENABLE: Habilita el inicio de sesión.&lt;/li&gt;
&lt;li&gt;DISABLE: Desactiva el inicio de sesión.&lt;/li&gt;
&lt;li&gt;Password: La nueva contraseña para asignar al inicio de sesión que se autentica mediante la autenticación de SQL Server&lt;/li&gt;
&lt;li&gt;hashed_password: El valor hash de la contraseña que se asignará al inicio de sesión mediante la autenticación de SQL Server.&lt;/li&gt;
&lt;li&gt;old_password: La contraseña anterior que usa la autenticación de SQL Server.&lt;/li&gt;
&lt;li&gt;MUST_CHANGE: Se usa cuando desea forzar el cambio de contraseña la primera vez que se usa el inicio de sesión después de la instrucción ALTER LOGIN.&lt;/li&gt;
&lt;li&gt;UNLOCK: Desbloqueará un inicio de sesión que ha sido bloqueado.&lt;/li&gt;
&lt;li&gt;database_name: La base de datos predeterminada para asignar al inicio de sesión&lt;/li&gt;
&lt;li&gt;language_name: El idioma predeterminado para asignar al inicio de
sesión.&lt;/li&gt;
&lt;li&gt;new_login_name: El nuevo nombre del inicio de sesión si está utilizando la instrucción ALTER LOGIN para cambiar el nombre de un inicio de sesión.&lt;/li&gt;
&lt;li&gt;CHECK_EXPIRATION: Determina si se aplica la política de caducidad de la contraseña. Debe especificar CHECK_EXPIRATION = ON cuando use la opción MUST_CHANGE.&lt;/li&gt;
&lt;li&gt;credential_name: El nombre de una credencial para asignar al inicio de sesión.&lt;/li&gt;
&lt;li&gt;NO CREDENTIAL: Elimina las credenciales asignadas del inicio de sesión.&lt;/li&gt;
&lt;li&gt;ADD CREDENTIAL: Agrega una credencial al inicio de sesión.&lt;/li&gt;
&lt;li&gt;DROP CREDENTIAL: Elimina una credencial del inicio de sesión&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ejemplos:&lt;br&gt;
Para cambiar la contraseña: &lt;code&gt;ALTER LOGIN techonthenet WITH PASSWORD = 'bestsite’;&lt;/code&gt;&lt;br&gt;
Para cambiar la contraseña y forzar el cambio: `&lt;code&gt;ALTER LOGIN techonthenet WITH PASSWORD = 'bestsite' MUST_CHANGE, CHECK_EXPIRATION = ON;&lt;/code&gt;&lt;br&gt;
Para deshabilitar el inicio de sesión: &lt;code&gt;ALTER LOGIN techonthenet DISABLE;&lt;/code&gt;&lt;br&gt;
Para habilitar un inicio de sesión: &lt;code&gt;ALTER LOGIN techonthenet ENABLE;&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Usuarios de la BD (User)
&lt;/h2&gt;

&lt;p&gt;Un usuario se refiere a una cuenta en la BD que se utiliza para acceder a la BD.&lt;br&gt;
Es la identidad del inicio de sesión cuando está conectado a una BD. Puede usar el mismo nombre que el inicio de sesión pero no es necesario.&lt;br&gt;
Los Logins y grants se le asignan a los usuarios, además de sus propios esquemas (schemas).&lt;br&gt;
Los usuarios por defecto en una BD:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dbo: Propietario (no puede borrarse de la BD)&lt;/li&gt;
&lt;li&gt;Guest: Permite a usuarios que no tienen cuenta en la
BD, que accedan a ella, pero hay que hacerle permiso
explícitamente.&lt;/li&gt;
&lt;li&gt;Information_schema: Permite ver los metadatos de
SQL Server.&lt;/li&gt;
&lt;li&gt;sys: Permite consultar las tablas y vistas del sistema,
procedimientos extendidos y otros objetos del
catálogo del sistema.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para ver los usuarios existentes de una BD, podemos ejecutar: &lt;br&gt;
&lt;code&gt;`USE master&lt;br&gt;
GO&lt;br&gt;
SELECT * FROM sys.database_principals`&lt;/code&gt;&lt;br&gt;
Para crear un usuario se usa: &lt;code&gt;Create user &amp;lt;username&amp;gt; for login &amp;lt;loginname&amp;gt;&lt;/code&gt;&lt;br&gt;
Para eliminar un usuario ejecuta: &lt;code&gt;DROP USER user_name;&lt;/code&gt; esta instrucción solo se ejecuta si el usuario no tiene ningun objeto en la BD.&lt;/p&gt;

&lt;p&gt;Un usuario puede también tener permisos o privilegios, esto se refiere a las reglas que rigen los niveles de acceso que tienen los elementos, se puede otorgar, revocar y denegar permisos con el comando:&lt;br&gt;
&lt;code&gt;`Use &amp;lt;database name&amp;gt;&lt;br&gt;
Grant &amp;lt;permission name&amp;gt; on &amp;lt;object name&amp;gt; to &amp;lt;username\principle&amp;gt;`&lt;/code&gt;&lt;br&gt;
Por ejemplo:&lt;br&gt;
&lt;code&gt;`USE TestDB&lt;br&gt;
GO&lt;br&gt;
Grant select on TestTable to TestUser`&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Roles
&lt;/h2&gt;

&lt;p&gt;Los roles pueden existir a nivel de instancia o de BD.&lt;br&gt;
A nivel de instancia, los logins pueden ser otorgados roles, llamados 'server roles' y no se pueden crear roles nuevos.&lt;br&gt;
A nivel de BD, los usuarios de la BD pueden ser otorgados roles y sí se pueden crear roles nuevos.&lt;br&gt;
Un rol de aplicación sirve para asignarle permisos a una aplicación, tiene una password y no contiene usuarios.&lt;br&gt;
Un rol facilita la configuración y mantenimiento del modelo de seguridad, es un grupo de privilegios relacionados, que se pueden otorgar al usuario, para crear un rol, se ejecuta: &lt;code&gt;CREATE ROLE &amp;lt;role name&amp;gt;&lt;/code&gt;&lt;br&gt;
Algunos de los privilegios otorgados a los roles del sistema son:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Connect: Crear tablas, vistas, sinónimos, secuencias, sesiones, etc.&lt;/li&gt;
&lt;li&gt;Resource: Crear procedimientos, secuencias, tablas, triggers, etc. El uso principal de este rol es restringir acceso a objetos de la BD.&lt;/li&gt;
&lt;li&gt;DBA: Tiene todos los privilegios del sistema.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para conceder privilegios a un rol, se ejecuta: &lt;code&gt;GRANT &amp;lt;permission name&amp;gt;, &amp;lt;permission name&amp;gt; TO &amp;lt;role name&amp;gt;;&lt;/code&gt;&lt;br&gt;
Para darle un rol a un usuario: &lt;code&gt;GRANT &amp;lt;role name&amp;gt; TO &amp;lt;username&amp;gt;, &amp;lt;username&amp;gt;;&lt;/code&gt;&lt;br&gt;
Para eliminar un privilegio de un rol: &lt;code&gt;REVOKE &amp;lt;permission name&amp;gt; FROM &amp;lt;role name&amp;gt;;&lt;/code&gt;&lt;br&gt;
Para eliminar un rol: &lt;code&gt;DROP ROLE &amp;lt;role name&amp;gt;&lt;/code&gt;&lt;/p&gt;

</description>
      <category>gratitude</category>
    </item>
    <item>
      <title>Iniciando con Ionic</title>
      <dc:creator>Beatriz Martínez Pérez</dc:creator>
      <pubDate>Sun, 01 Jan 2023 23:08:18 +0000</pubDate>
      <link>https://dev.to/tris460/iniciando-con-ionic-4c32</link>
      <guid>https://dev.to/tris460/iniciando-con-ionic-4c32</guid>
      <description>&lt;h2&gt;
  
  
  ¿Qué es Ionic?
&lt;/h2&gt;

&lt;p&gt;Es un framework multiplataforma, libre y gratuito que nos da herramientas para crear aplicaciones nativas de iOS y Android, con ayuda de bibliotecas, frameworks conocidos (Angular, React y Vue) y lenguajes de programación conocidos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Iniciar
&lt;/h2&gt;

&lt;p&gt;Instalar vía npm: &lt;code&gt;npm i -g @ionic/cli&lt;/code&gt;&lt;br&gt;
Desinstalar: &lt;code&gt;npm uninstall -g ionic&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Estructura del proyecto
&lt;/h2&gt;

&lt;p&gt;src/&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;app/&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;app-routing.module.ts&lt;br&gt;
app.component.html&lt;br&gt;
app.component.spec.ts&lt;br&gt;
app.component.ts&lt;br&gt;
app.module.ts&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;assets/&lt;br&gt;
environments/&lt;br&gt;
theme/&lt;br&gt;
global.scss&lt;br&gt;
index.html&lt;br&gt;
main.ts&lt;br&gt;
polyfills.ts&lt;br&gt;
test.ts&lt;br&gt;
zone-flags.ts&lt;/p&gt;


&lt;/blockquote&gt;

&lt;p&gt;El directorio src/app/ contiene los archivos principales que se usarán para editar el proyecto. &lt;/p&gt;

&lt;h2&gt;
  
  
  Comandos básicos
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;ionic -v&lt;/code&gt; Devuelve la versión actual de Ionic&lt;br&gt;
&lt;code&gt;ionic --help&lt;/code&gt; Muestra ayuda&lt;br&gt;
&lt;code&gt;ionic start project-name&lt;/code&gt; Crea un proyecto&lt;br&gt;
&lt;code&gt;ionic start project-name template-project&lt;/code&gt; Genera un proyecto con la plantilla indicada (tabs, sidemenu o blank)&lt;br&gt;
&lt;code&gt;ionic serve&lt;/code&gt; Inicia el proyecto en un servidor local&lt;br&gt;
&lt;code&gt;ionic generate&lt;/code&gt; Crea una nueva característica (páginas, componentes, servicios, módulos, clases, etc.)&lt;br&gt;
&lt;code&gt;ionic g tipo-caracerística "nombre"&lt;/code&gt; Atajo para crear una característica dado un nombre&lt;/p&gt;

&lt;h2&gt;
  
  
  Plantillas
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;tabs: Una vista basada en pestañas&lt;/li&gt;
&lt;li&gt;sidemenu: La vista tendrá un menú lateral&lt;/li&gt;
&lt;li&gt;blank: Un proyecto vacío con una sola página&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Características
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Páginas
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;ionic g page mi_pagina&lt;/code&gt; Crear una página&lt;br&gt;
Por defecto, al crearlas, se agregan como hijas de la carpeta app/, si, por ejemplo, estamos usando la plantilla 'tabs' y queremos que 'mi_pagina' sea hija de 'tabs', hay que editar el archivo &lt;code&gt;app-routing.module.ts&lt;/code&gt;, eliminando la declaración de 'mi_pagina' y agregándola en el archivo &lt;code&gt;tabs-routing.module.ts&lt;/code&gt;.&lt;br&gt;
Hay que tener cuidado de poner la ruta correctamente.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z8KIyDMO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ge9ezlnkr31m69ihir9v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z8KIyDMO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ge9ezlnkr31m69ihir9v.png" alt="Ionic pages organization" width="880" height="395"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Servicios
&lt;/h3&gt;

&lt;p&gt;Permiten compartir información en todas las páginas ya que sus métodos y atributos son públicos a menos que usemos 'private'. Es recomendable tener un servicio por cada tabla que exista en la base de datos.&lt;br&gt;
&lt;code&gt;ionic g service folder/mi_servicio&lt;/code&gt; Crea un servicio&lt;br&gt;
Para poder usarlo:&lt;br&gt;
&lt;code&gt;import { mi_servicioService } from './folder/mi_servicio.service';&lt;/code&gt; Importar el servicio&lt;br&gt;
&lt;code&gt;mi-variable;&lt;/code&gt; Crear una variable nueva&lt;br&gt;
&lt;code&gt;constructor (public servicio1: mi_servicioService) {&lt;/code&gt; Crear un objeto en el constructor&lt;br&gt;
&lt;code&gt;this.mi-variable = this.servicio1.atributo1; }&lt;/code&gt; Almacena el valor de la variable del servicio, en la variable del módulo donde lo estamos importando&lt;/p&gt;

&lt;h3&gt;
  
  
  Componentes
&lt;/h3&gt;

&lt;p&gt;Nos sirven para encapsular y reutilizar el código, son la base de la aplicación. Al crear un componente, se crea una carpeta que tiene un archivo HTML, CSS y un TS, esta nueva carpeta se crea dentro del componente principal (app/).&lt;br&gt;
&lt;code&gt;ng g c folder/mi_componente&lt;/code&gt; Crea un nuevo componente&lt;br&gt;
Para usar el componente, se debe poner su selector (etiqueta HTML) en el archivo HTML y automáticamente se va a importar su contenido.&lt;/p&gt;

&lt;h2&gt;
  
  
  Librerías importantes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Router
&lt;/h3&gt;

&lt;p&gt;Nos permite navegar entre las distintas páginas generadas, para usarlo, necesitamos importarlo en el archivo TypeScript de cada módulo (conjunto de archivos .ts, .html, .css, etc.) de donde queramos usarlo. &lt;br&gt;
&lt;code&gt;import { Router } from '@angular/router';´ Importar la librería&lt;br&gt;
&lt;/code&gt;constructor (private router: Router) { }&lt;code&gt;Crear un objeto de este tipo para poder acceder a su funcionalidad&lt;br&gt;
&lt;/code&gt;this.router.navigate(['página']);` Función para navegar entre páginas&lt;/p&gt;

&lt;h3&gt;
  
  
  Alert
&lt;/h3&gt;

&lt;p&gt;Permite enviar alertas al usuario, para usarlo, al igual que la librería anterior, hay que importarlo en el archivo TypeScript.&lt;br&gt;
&lt;code&gt;import { AlertController } from '@ionic/angular';&lt;/code&gt; Importar la librería&lt;br&gt;
&lt;code&gt;constructor (public alert: AlertController) {}&lt;/code&gt; Crear el objeto de la librería&lt;br&gt;
&lt;code&gt;&lt;/code&gt;&lt;code&gt;const mi_alerta = await this.alert.create( {&lt;br&gt;
header: 'Mi título',&lt;br&gt;
subheader: 'Mi subtítulo',&lt;br&gt;
message: 'Mi mensaje',&lt;br&gt;
button: ['Botón0', 'Botón1'];&lt;/code&gt;&lt;code&gt;&lt;/code&gt; Crear la alerta personalizada&lt;br&gt;
&lt;code&gt;await mi_alerta.present();&lt;/code&gt; Ejecutar la alerta&lt;/p&gt;

&lt;h2&gt;
  
  
  Conectarse a una API
&lt;/h2&gt;

&lt;p&gt;Podemos usar HttpClient para manejar las peticiones y respuestas externas.&lt;br&gt;
Es recomendable hacerlo en un servicio, así, podemos usarlo en cualquier página de nuestra aplicación.&lt;br&gt;
&lt;code&gt;import { HttpClient } from '@angular/common/http';&lt;/code&gt; Se importa en el servicio.&lt;br&gt;
&lt;code&gt;constructor (private http: HttpClient) &lt;/code&gt; Crear el objeto de la librería&lt;br&gt;
&lt;code&gt;this.http.get(urlApi).subscribe() &lt;/code&gt; Accede a la URL y se suscribe a los cambios&lt;br&gt;
&lt;code&gt;response =&amp;gt; console.log(response)&lt;/code&gt; Imprime la respuesta si la petición es correcta&lt;br&gt;
&lt;code&gt;error =&amp;gt; console.error(error) );&lt;/code&gt; Imprime el error y se cierra el paréntesis del 'subscribe' y la llave del constructor&lt;/p&gt;

&lt;h2&gt;
  
  
  Documentación oficial
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://ionicframework.com/"&gt;https://ionicframework.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ionic</category>
      <category>beginners</category>
      <category>mobile</category>
    </item>
    <item>
      <title>Comandos para la administración de Bases de Datos NoSQL con Mongo</title>
      <dc:creator>Beatriz Martínez Pérez</dc:creator>
      <pubDate>Sun, 18 Sep 2022 20:16:30 +0000</pubDate>
      <link>https://dev.to/tris460/comandos-para-la-administracion-de-bases-de-datos-nosql-con-mongo-54kb</link>
      <guid>https://dev.to/tris460/comandos-para-la-administracion-de-bases-de-datos-nosql-con-mongo-54kb</guid>
      <description>&lt;h2&gt;
  
  
  ¿Qué es?
&lt;/h2&gt;

&lt;p&gt;Una base de datos es un espacio en donde podemos guardar los datos de usuarios, estadísticas, precios, productos, etc. Existen diferentes modelos que se pueden adoptar dependiendo del tipo de aplicación que se desee generar.&lt;br&gt;
Decir que una base de datos es NoSQL se refiere a que no es relacional, están basadas en documentos y su esquema ágil permite procesar rápidamente datos sin estructura y que requieren iteraciones rápidas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Operadores de comparacion en Mongo
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;$eq&lt;/strong&gt; - Igual a&lt;br&gt;
&lt;strong&gt;$ne&lt;/strong&gt; - Diferente a &lt;br&gt;
&lt;strong&gt;$gt&lt;/strong&gt; - Mayor a&lt;br&gt;
&lt;strong&gt;$gte&lt;/strong&gt; - Mayor o igual a&lt;br&gt;
&lt;strong&gt;$lt&lt;/strong&gt; - Menor a&lt;br&gt;
&lt;strong&gt;$lte&lt;/strong&gt; - Menor o igual a&lt;br&gt;
&lt;strong&gt;$in&lt;/strong&gt; - Valores dentro de un array&lt;br&gt;
&lt;strong&gt;$nin&lt;/strong&gt; - Valores que no estén dentro de un array&lt;/p&gt;

&lt;h2&gt;
  
  
  Operadores lógicos
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;$or&lt;/strong&gt; - Filtra  los documentos que cumplan con una condición u otra.&lt;br&gt;
&lt;strong&gt;$and&lt;/strong&gt; - Filtra los documentos que cumplan con todas las condiciones.&lt;br&gt;
&lt;strong&gt;$not&lt;/strong&gt; - Filtra los documentos que no coincidan con la condición.&lt;br&gt;
&lt;code&gt;{field: {$not : {condition}}}&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Comandos para un CRUD
&lt;/h2&gt;

&lt;p&gt;Create: insert y save.&lt;br&gt;
Read: find y pretty.&lt;br&gt;
Update: update, multi y upsert.&lt;br&gt;
Delete: remove.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comandos básicos
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;show dbs&lt;/strong&gt; - Comando para ver las bases de datos existentes.&lt;br&gt;
&lt;strong&gt;use miBD&lt;/strong&gt; - Usar la base de datos 'miDB' o crearla si no existe.&lt;br&gt;
&lt;strong&gt;db&lt;/strong&gt; - Ver en cuál BD estamos.&lt;br&gt;
&lt;strong&gt;db.createCollection("miColeccion")&lt;/strong&gt; - Crear una colección.&lt;br&gt;
&lt;strong&gt;show collections&lt;/strong&gt; - Ver la lista de colecciones existentes.&lt;br&gt;
&lt;strong&gt;db.miColeccion.drop()&lt;/strong&gt; - Elimina la colección.&lt;br&gt;
&lt;strong&gt;db.dropDatabase()&lt;/strong&gt; - Elimina toda la base de datos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Insertar documentos
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;db.miColeccion.insertOne({"campo":"valor","campo":"valor"})&lt;/strong&gt; - Insertar un documento.&lt;br&gt;
&lt;strong&gt;db.miColeccion.insertMany([{...}, {...}, {...}])&lt;/strong&gt; - Insertar varios documentos.&lt;br&gt;
&lt;strong&gt;db.miColeccion.save({_id:1, "campo": "valor", "campo": "valor"})&lt;/strong&gt; - Es otra forma de guardar un documento. El campo '_id' es opcional y no genera duplicidad si hay dos ID iguales.&lt;/p&gt;

&lt;h2&gt;
  
  
  Actualizar documentos
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;db.miColeccion.update({campoID:"valor"}, {campo:"valor"})&lt;/strong&gt; - Actualiza los datos que especifiquemos, dado el documento a editar (campoID).&lt;/p&gt;

&lt;h2&gt;
  
  
  Eliminar documentos
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;db.miColeccion.remove({_id: 1})&lt;/strong&gt; - Elimina el documento con el ID especificado.&lt;/p&gt;

&lt;h2&gt;
  
  
  Filtrar documentos
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;db.miColeccion.find()&lt;/strong&gt; - Ver los documentos almacenados.&lt;br&gt;
&lt;strong&gt;db.miColeccion.find().pretty()&lt;/strong&gt; - Ver los documentos almacenados de manera legible.&lt;br&gt;
&lt;strong&gt;db.miColeccion.find({"campo": "valor"}).pretty()&lt;/strong&gt; - Devuelve el documento que coincida con el campo/valor que especificamos, con un formato legible.&lt;br&gt;
&lt;strong&gt;db.miColeccion.find({},{campo1:1, campo2:2, _id:0})&lt;/strong&gt; - Retorna todos los documentos pero solo muestra los campos especificados.&lt;br&gt;
&lt;strong&gt;db.miColeccion.find().pretty({campo:-1})&lt;/strong&gt; - Mostrar los registros ordenados por 'campo'. Ascendente: 1, descendente: -1.&lt;br&gt;
&lt;strong&gt;db.miColeccion.find({campo: {$gte: new Date(1970,1,1)}})&lt;/strong&gt; - Filtra 'campo' a partir de la fecha especificada (1970).&lt;/p&gt;

&lt;h2&gt;
  
  
  Documento JS en Mongo
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;load("C://ruta/del/archivo.js")&lt;/strong&gt; - Carga el archivo JS y lo ejecuta.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Cómo escribir un documento JS para ejecutar en Mongo?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;db = db.getSiblingDB('miBD')&lt;/strong&gt; - Este comando es equivalente a 'use', sirve para elegir la base de datos que queremos usar.&lt;br&gt;
&lt;strong&gt;db.adminCommand('listDatabases')&lt;/strong&gt; - Es el equivalente a show dbs.&lt;br&gt;
&lt;strong&gt;db.getCollectionNames()&lt;/strong&gt; - Nos mostrará los nombres de las colecciones existentes.&lt;br&gt;
&lt;strong&gt;db.getUsers()&lt;/strong&gt; - Retorna los usuarios.&lt;br&gt;
&lt;strong&gt;db.getRoles({showBuiltinRoles: true})&lt;/strong&gt; - Este comando muestra los roles y los permisos configurados.&lt;br&gt;
&lt;strong&gt;db.adminCommand({'getLog': ''})&lt;/strong&gt; - Muestra los logs.&lt;br&gt;
&lt;strong&gt;cursor = db.miColeccion.find()&lt;/strong&gt; - Asigna los documentos registrados a 'cursor'.&lt;br&gt;
&lt;strong&gt;while(cursor.hasNext()) { printjson(cursor.next()); }&lt;/strong&gt; - Recorrer los documentos e imprimirlos con un formato JSON.&lt;/p&gt;

</description>
      <category>database</category>
      <category>nosql</category>
      <category>beginners</category>
      <category>mongodb</category>
    </item>
    <item>
      <title>Conceptos básicos de Docker</title>
      <dc:creator>Beatriz Martínez Pérez</dc:creator>
      <pubDate>Thu, 18 Nov 2021 20:44:10 +0000</pubDate>
      <link>https://dev.to/tris460/iniciando-con-docker-2lfi</link>
      <guid>https://dev.to/tris460/iniciando-con-docker-2lfi</guid>
      <description>&lt;p&gt;Docker te permite construir, distribuir y ejecutar cualquier app en cualquier lugar, mediante contenedores.&lt;br&gt;
Para poder usarlo debes ingresar a &lt;a href="https://www.docker.com/"&gt;https://www.docker.com/&lt;/a&gt; y descargar 'Docker desktop' y crear una cuenta en DockerHub.&lt;/p&gt;
&lt;h3&gt;
  
  
  Conceptos importantes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Contenedores: Dónde va a correr la app, sirve para poder compartir las imágenes con otros servidores, computadoras, etc. Es una agrupación de procesos aislados del sistema, es decir, como si se estuviera corriendo una máquina virtual en tu computadora, pero mucho mejor.&lt;/li&gt;
&lt;li&gt;Imágenes: Es la encapsulación del contenedor a compartir, lo que tú creas para que otros usuarios lo usen.&lt;/li&gt;
&lt;li&gt;Volúmenes de datos: Archivos del sistema, pueden ser archivos, carpetas, imágenes, etc. &lt;/li&gt;
&lt;li&gt;Redes: Permiten la comunicación entre servidores, son conexiones básicamente.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Comandos importantes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;docker login&lt;/strong&gt; Inicia sesión en DockerHub para poder usar el código que ya está escrito y compartir tu código.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;docker run &lt;code&gt;&amp;lt;contenedor&amp;gt;&lt;/code&gt;&lt;/strong&gt; Ejecuta el contenedor.

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--name &amp;lt;nombre&amp;gt;&lt;/code&gt; Le asigna un nombre al contenedor.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--mount src=&amp;lt;nombre_volumen&amp;gt;,dst=&amp;lt;ruta_contenedor&amp;gt;&lt;/code&gt; Asigna un volumen al contenedor, como &lt;code&gt;-v&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-i&lt;/code&gt; Abre el modo interactivo.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-t&lt;/code&gt; Ejecuta su terminal.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-d&lt;/code&gt; Lo ejecuta en segundo plano.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-p &amp;lt;puerto_local&amp;gt;:&amp;lt;puerto_contenedor&amp;gt;&lt;/code&gt; Expone un puerto del contenedor para acceder en la máquina local.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-v &amp;lt;ruta_local&amp;gt;:&amp;lt;ruta_contenedor&amp;gt;&lt;/code&gt; Copia todos la data de la ruta del contenedor en la ruta local especificada. Crea un volumen.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--rm&lt;/code&gt; Cuando se cierra el contenedor, se elimina.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--env &amp;lt;nombre_variable&amp;gt;=&amp;lt;valor&amp;gt;&lt;/code&gt; Define una variable de entorno.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--scale &amp;lt;nombre_contenedor&amp;gt;=&amp;lt;número&amp;gt;&lt;/code&gt; Crea 'n' instancias del contenedor&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--memory &amp;lt;cantidad_memoria&amp;gt;&lt;/code&gt; Limita el uso de memoria.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;docker ps&lt;/strong&gt; Lista los contenedores activos y su información.

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-a&lt;/code&gt; Muestra también los contenedores inactivos.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-q&lt;/code&gt; Muestra solo los ID de los contenedores.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-l&lt;/code&gt; Muestra solo la información del último proceso.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;docker inspect &lt;code&gt;&amp;lt;id_contenedor | nombre_contenedor&amp;gt;&lt;/code&gt;&lt;/strong&gt; Muestra información más completa sobre el contenedor dado su ID o nombre.

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--format '{{&amp;lt;atributo&amp;gt;.&amp;lt;propiedad&amp;gt;}}'&lt;/code&gt; Retorna solo la información solicitada.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;docker rename &lt;code&gt;&amp;lt;actual&amp;gt; &amp;lt;nuevo&amp;gt;&lt;/code&gt;&lt;/strong&gt; Cambia el nombre de un contenedor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;docker rm &lt;code&gt;&amp;lt;id_contenedor | nombre_contenedor&amp;gt;&lt;/code&gt;&lt;/strong&gt; Elimina el contenedor seleccionado.

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-f&lt;/code&gt; Fuerza el borrado.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;docker container prune&lt;/strong&gt; Elimina todos los contenedores.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;docker exec &lt;code&gt;&amp;lt;nombre_contenedor&amp;gt;&lt;/code&gt;&lt;/strong&gt; Conectar con un contenedor que ya está corriendo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;docker stop &lt;code&gt;&amp;lt;nombre_contenedor&amp;gt;&lt;/code&gt;&lt;/strong&gt; Mata un proceso.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;docker logs&lt;/strong&gt; Muestra los logs.

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-f&lt;/code&gt; Se queda esperando a que lleguen más logs.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--tail &amp;lt;número&amp;gt;&lt;/code&gt; Muestra los últimos 'n' logs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;docker tag &lt;code&gt;&amp;lt;nombre_contenedor&amp;gt; &amp;lt;nuevo_nombre_contenedor&amp;gt;&lt;/code&gt;&lt;/strong&gt; Renombra la etiqueta del contenedor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;docker history &lt;code&gt;&amp;lt;nombre_contenedor&amp;gt;&lt;/code&gt;&lt;/strong&gt; Muestra los cambios hechos al contenedor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;docker system prune&lt;/strong&gt; Borra todo lo que este inactivo.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;docker stats&lt;/strong&gt; Ver los recursos que está consumiendo el contenedor.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;docker volume ls&lt;/strong&gt; Lista los volúmenes activos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;docker volume create &lt;code&gt;&amp;lt;nombre_volumen&amp;gt;&lt;/code&gt;&lt;/strong&gt; Crea un volumen.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;docker volume prune&lt;/strong&gt; Borra los volúmenes inactivos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;docker cp &lt;code&gt;&amp;lt;archivo&amp;gt; &amp;lt;nombre_contenedor&amp;gt;:&amp;lt;ruta_local&amp;gt;&lt;/code&gt;&lt;/strong&gt; Copia un archivo del contenedor a la ruta local asignada&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;docker cp &lt;code&gt;&amp;lt;nombre_contenedor&amp;gt;:/&amp;lt;directorio&amp;gt; &amp;lt;ruta_local&amp;gt;&lt;/code&gt;&lt;/strong&gt; Copia un directorio desde el contenedor.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;docker image ls&lt;/strong&gt; Lista las imágenes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;docker pull :&lt;/strong&gt; Trae la imagen desde DockerHub.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;docker build &lt;code&gt;&amp;lt;nombre_contenedor&amp;gt;&lt;/code&gt; .&lt;/strong&gt; Construye una imagen.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-t&lt;/code&gt; Agrega una etiqueta a la imagen.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;docker push &lt;code&gt;&amp;lt;nombre_contenedor&amp;gt;&lt;/code&gt;&lt;/strong&gt; Publica el contenedor en DockerHub.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;docker network ls&lt;/strong&gt; Muestra las redes existentes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;docker network create &lt;code&gt;&amp;lt;nombre_red&amp;gt;&lt;/code&gt;&lt;/strong&gt; Crea una red.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--attachable&lt;/code&gt; Permite que cualquiera se conecte a la red.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;docker network inspect &lt;code&gt;&amp;lt;nombre_red&amp;gt;&lt;/code&gt;&lt;/strong&gt; Muestra información de esa red.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;docker network connect &lt;code&gt;&amp;lt;nombre_red&amp;gt; &amp;lt;nombre_contenedor&amp;gt;&lt;/code&gt;&lt;/strong&gt; Conecta un contenedor a una red.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;docker network prune&lt;/strong&gt; Elimina todas las redes que no estén siendo usadas.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;docker-compose up&lt;/strong&gt; Corre todo lo que definimos en el archivo docker-compose.yml (redes, servicios, contenedores, etc).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-d&lt;/code&gt; Lo corre en segundo plano.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;docker-compose ps&lt;/strong&gt; Muestra los contenedores activos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;docker-componse logs&lt;/strong&gt; Muestra los logs de los servicios/contenedores.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-f&lt;/code&gt; Muestra los logs conforme llegan.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;nombre_contenedor&amp;gt;&lt;/code&gt; Muestra los logs de solo ese servicio.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;docker-compose down&lt;/strong&gt; Apaga los contenedores y elimina todo lo que tenga que ver con ellos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;docker-compose build &lt;code&gt;&amp;lt;nombre_contenedor&amp;gt;&lt;/code&gt;&lt;/strong&gt; Construye una imagen a partir de los archivos que tiene en disco, basandose en el archivo docker-compose.yml.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Dockerfile
&lt;/h3&gt;

&lt;p&gt;Es un archivo de texto plano con instrucciones necesarias para crear una imagen.&lt;br&gt;
Una estructura básica puede ser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM node:12 //En qué se basa
COPY [".", "/usr/src/"] //Copia archivos
WORKDIR /usr/src/ //Cambia de directorio (como cd)
RUN npm install //Corre este comando
EXPOSE 3000 //Expone el puerto para usarlo en local
CMD ["node", "index.js"] //Comando a ejecutar cuando se corra el contenedor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Docker Compose
&lt;/h3&gt;

&lt;p&gt;Permite escribir en un archivo lo que queremos que Docker realice sin usar los comandos. El archivo es docker-compose.yml. Es parecido a un archivo JSON, aquí importa el tabulado, es decir que si no pones el espaciado correcto, la aplicación no funcionará.&lt;br&gt;
Ejemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: "3.8" //Versión de DockerCompose
services: //Componentes a ejecutarse
  app: //Servicio
    image: ubuntu //Imagen en la que se va a basar el contenedor
    environment: //Define las variables de entorno
      MONGO_URL: "mongodb://db:27017/test"
    depends_on: //Servicios que deben existir para que funcione
      - db
    ports: //Puertos a exponer y en que puerto
      -"3000:3000"
      -"2000-20003:2000" //Expone un rango de puertos
    volumes: //Define un volumen
      -.:/usr/src/ //De dónde toma los datos y en dónde los guarda
    build: . // Dónde va a construir la app
  db:
    image: mongo
  command: npx nodemon index.js //Qué comando se ejecutará
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Docker Compose Override
&lt;/h3&gt;

&lt;p&gt;Este archivo es como docker-compose.yml pero para cuando queremos trabajar en nuestro local sin hacer cambios que puedan afectar al resto del equipo.&lt;br&gt;
No podemos dejar vacío este archivo, ya que puede generar errores.&lt;br&gt;
Podríamos poner solo &lt;code&gt;version: "3.8"&lt;/code&gt; para que funcione, ya que 'hereda' los datos de docker-compose.yml, si hay líneas repetidas, el archivo docker-componse.override.yml lo sobrescribe.&lt;br&gt;
Es aconsejable no sobrescribir los puertos, sino dejarlos solo en un archivo, esto para evitar errores.&lt;/p&gt;
&lt;h3&gt;
  
  
  Docker Ignore
&lt;/h3&gt;

&lt;p&gt;Aquí definimos los archivos que no serán tomados en cuenta para realizar el build. El archivo se llama: .dockerignore.&lt;br&gt;
Su sintaxis es:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*.log
.dockerignore
.git
Dockerfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>docker</category>
      <category>beginners</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
