1643615024
Para un inmigrante de primera generación puede ser todo un desafío comprender cómo funciona el sistema financiero de los Estados Unidos. Como residente no estadounidense, usted es elegible para obtener un préstamo personal, pero, dependiendo de su prestamista, tendrá que cumplir con ciertos requisitos.
Así como ocurre con otras solicitudes de préstamo, los prestamistas prestarán atención a su habilidad financiera y en si puede o no devolver el dinero prestado. También estarán interesados en obtener una constancia laboral para estar seguros de que usted puede devolver el pago.
A continuación, todo lo que necesita saber para préstamos personales cuando no hay crédito:
¿Está considerando solicitar un préstamo personal en su estatus de inmigrante? Debido a que eso es un factor de riesgo alto, su solicitud se examinará a fondo. Necesita prepararse con eso en mente.
He aquí algunos consejos:
Cuando haga su solicitud, usted necesitará una copia de su solicitud de empleo, tarjeta de residencia o visa. Puede presentar los formularios I-766, I-765, 1-94 o 1-797A. Además de esto, necesitará un puntaje FICO. Por último, si acaba de mudarse a los Estados Unidos y aún no cuenta con un historial crediticio, necesitará documentos e información adicionales conocidos como el paquete crediticio.
Por ejemplo, si usted cuenta con historial crediticio en su país de origen, puede obtener información del historial crediticio de una agencia de su país para demostrar su solvencia.
A medida que encuentre información adicional, busque datos en distintas cuentas para demostrar que usted hace sus pagos a tiempo. Podría usar los pagos del alquiler, seguro o servicios. Puede aumentar la posibilidad de que lo aprueben si consigue que un ciudadano estadounidense con excelente historial crediticio sea cosignatario con usted.
Por último, cuando esté llenando su solicitud de préstamo asegúrese de tener consigo toda la información personal que necesita. Puede ser su tarjeta de identificación o su licencia de conducir. También necesita tener a la mano un comprobante de domicilio, este puede ser el recibo de algún servicio u otros documentos como arrendamientos que contengan su dirección.
Tenga a la mano formularios de verificación de ingresos tales como W-2 o estados de cuenta bancarios. Tenga a la mano su información personal como su contacto y número de seguro social. También tendrá que poner información sobre sus préstamos, educación y empleo.
Hay muchos prestamistas que ofrecen préstamos personales a inmigrantes y residentes no estadounidenses que no cuentan con crédito. Sin embargo, ya que los residentes no estadounidenses tienen necesidades muy particulares, puede que los términos del acuerdo de cada prestamista varíen según sus necesidades y circunstancias particulares. Por lo tanto, es esencial que usted revise y compare entre diferentes prestamistas para obtener el mejor trato.
En vez de estar contactando a cada uno de los prestamistas para conocer su oferta usted puede utilizar Crediverso para compararlos. Crediverso es un sitio confiable en donde puede obtener información detallada sobre los mejores prestamistas de préstamos personales sin crédito, en especial para inmigrantes de primera generación provenientes de Latinoamérica.
El sitio de internet compara entre diferentes prestamistas de préstamos personales e incluye consejos para hacer su solicitud. Además, tienen un blog donde usted puede interactuar con otros residentes no estadounidenses y una sección de comunidad donde podrá obtener consejos para manejar sus finanzas. Haga su búsqueda más sencilla y obtenga la mejor oferta visitando hoy nuestro sitio web.
1643615024
Para un inmigrante de primera generación puede ser todo un desafío comprender cómo funciona el sistema financiero de los Estados Unidos. Como residente no estadounidense, usted es elegible para obtener un préstamo personal, pero, dependiendo de su prestamista, tendrá que cumplir con ciertos requisitos.
Así como ocurre con otras solicitudes de préstamo, los prestamistas prestarán atención a su habilidad financiera y en si puede o no devolver el dinero prestado. También estarán interesados en obtener una constancia laboral para estar seguros de que usted puede devolver el pago.
A continuación, todo lo que necesita saber para préstamos personales cuando no hay crédito:
¿Está considerando solicitar un préstamo personal en su estatus de inmigrante? Debido a que eso es un factor de riesgo alto, su solicitud se examinará a fondo. Necesita prepararse con eso en mente.
He aquí algunos consejos:
Cuando haga su solicitud, usted necesitará una copia de su solicitud de empleo, tarjeta de residencia o visa. Puede presentar los formularios I-766, I-765, 1-94 o 1-797A. Además de esto, necesitará un puntaje FICO. Por último, si acaba de mudarse a los Estados Unidos y aún no cuenta con un historial crediticio, necesitará documentos e información adicionales conocidos como el paquete crediticio.
Por ejemplo, si usted cuenta con historial crediticio en su país de origen, puede obtener información del historial crediticio de una agencia de su país para demostrar su solvencia.
A medida que encuentre información adicional, busque datos en distintas cuentas para demostrar que usted hace sus pagos a tiempo. Podría usar los pagos del alquiler, seguro o servicios. Puede aumentar la posibilidad de que lo aprueben si consigue que un ciudadano estadounidense con excelente historial crediticio sea cosignatario con usted.
Por último, cuando esté llenando su solicitud de préstamo asegúrese de tener consigo toda la información personal que necesita. Puede ser su tarjeta de identificación o su licencia de conducir. También necesita tener a la mano un comprobante de domicilio, este puede ser el recibo de algún servicio u otros documentos como arrendamientos que contengan su dirección.
Tenga a la mano formularios de verificación de ingresos tales como W-2 o estados de cuenta bancarios. Tenga a la mano su información personal como su contacto y número de seguro social. También tendrá que poner información sobre sus préstamos, educación y empleo.
Hay muchos prestamistas que ofrecen préstamos personales a inmigrantes y residentes no estadounidenses que no cuentan con crédito. Sin embargo, ya que los residentes no estadounidenses tienen necesidades muy particulares, puede que los términos del acuerdo de cada prestamista varíen según sus necesidades y circunstancias particulares. Por lo tanto, es esencial que usted revise y compare entre diferentes prestamistas para obtener el mejor trato.
En vez de estar contactando a cada uno de los prestamistas para conocer su oferta usted puede utilizar Crediverso para compararlos. Crediverso es un sitio confiable en donde puede obtener información detallada sobre los mejores prestamistas de préstamos personales sin crédito, en especial para inmigrantes de primera generación provenientes de Latinoamérica.
El sitio de internet compara entre diferentes prestamistas de préstamos personales e incluye consejos para hacer su solicitud. Además, tienen un blog donde usted puede interactuar con otros residentes no estadounidenses y una sección de comunidad donde podrá obtener consejos para manejar sus finanzas. Haga su búsqueda más sencilla y obtenga la mejor oferta visitando hoy nuestro sitio web.
1655243220
weather_widget
Simple weather related widget, which can be freely combined to form a variety of weather backgrounds
depend
Add this to your package's pubspec.yaml file:
dependencies:
weather_widget: ^1.0.6
Weatherwidget is easy to use, just add weatherwidget to start using
WeatherWidget(
size:Size.infinite,
weather:'Sunny',
sunConfig:SunConfig()
),
This will add a sunny day using the default settings
or other weather type
(Note: Raindrops and snowflakes need to specify the default number, and they will move randomly within the range)
WeatherWidget(
size:Size.infinite,
weather:'Cloudy',
cloudConfig:CloudConfig()
),
WeatherWidget(
size:Size.infinite,
weather:'Rainy',
rainConfig:RainConfig(
rainNum:'the num of raindrops you want'
)
),
WeatherWidget(
size:Size.infinite,
weather:'Snowy',
snowConfig:SnowConfig(
snowNum:'the num of snowflakes you want'
)
),
WeatherWidget(
size:Size.infinite,
weather:'Thunder',
thunderConfig:ThunderConfig()
),
Of course, each config contains other settings, such as the range, size, length, falling speed and color of random raindrops. You can use them to create hailstones and other weather features
If the default weather is not enough, you can use individual widgets and stack() widget to piece together the desired weather
Like this sunset breeze, etc
These are include in this widget
background
BackgroundWidget(List<Color>,size)
cloud
CloudWidget (Color)
A single random raindrop
RainWidget (
@required rainRangeXStart, #X-axis starting point of raindrop random occurrence
@required rainRangeXEnd,
@required rainRangeYStart,
@required rainRangeYEnd,
@required durationRangeStartMill, #Minimum time to fall
@required durationRangeEndMill,
rainLength,
rainWidth,
rainColor,
rainCurve #Curve of falling animation
)
A single random snowflake
SnowWidget (
this.snowAreaXStart, #X-axis starting point of snowflake random occurrence
this.snowAreaXEnd,
this.snowWaveRangeMin, #The minimum floating distance of snowflakes
this.snowWaveRangeMax,
this.snowFallSecMin, #Minimum time of snowflake falling
this.snowFallSecMax,
this.snowWaveSecMin, #Minimum time for snowflake to float
this.snowWaveSecMax,
this.snowSize,
this.snowColor,
this.snowAreaYStart, #Y-axis point of snowflake occurrence
this.snowAreaYEnd,
this.waveCurve, #Floating animation curve
this.fadeCurve #Vanish animation curve
)
A single flash
ThunderWidget (
this.flashMillStart, #Minimum flashing time
this.flashMillEnd,
this.pauseMillStart, #Minimum interval time
this.pauseMillEnd,
this.blurStyle, #blur model
this.blurSigma,
this.points,
this.color,
this.width
)
a single wind
WindWidget (
this.pauseMillStart, #Minimum interval time
this.pauseMillEnd,
this.windPositionY, #Y-axis point of wind occurrence
this.windSlideMill, #Passing time
this.windColor,
this.windWidth,
this.windSlideXEnd,
this.windSlideXStart,
this.windGap, #line spacing in a wind
this.blurStyle,
this.blurSigma
)
Using sunny weather by set the WeatherWidget background config in a sunConfig()
Run this command:
With Flutter:
$ flutter pub add weather_widget
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
weather_widget: ^1.0.6
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:weather_widget/WeatherWidget.dart';
import 'package:weather_widget/example/main.dart';
example/main.dart
import 'package:flutter/material.dart';
import 'package:weather_widget/WeatherWidget.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: WeatherWidget(
size: Size.infinite,
weather: 'Thunder',
thunderConfig:ThunderConfig(
thunderWidth:12
)
)
);
}
}
chinese 中文README
Author: Carendule
Source Code: https://github.com/carendule/WeatherWidget
License: View license
1594961100
Cuando se habla de disponer en contenedores una aplicación, se hace referencia al proceso de adaptación de una aplicación y sus componentes para poder ejecutarla en entornos ligeros conocidos como contenedores. Estos entornos están aislados, son desechables y se pueden utilizar para desarrollar, probar e implementar aplicaciones en la producción.
En esta guía, usaremos Docker Compose con el propósito de disponer en contenedores una aplicación de Laravel para el desarrollo. Al finalizar, dispondrá de una aplicación Laravel de demostración funcional en tres contenedores de servicios separados:
app
con PHP7.4-FPM;db
con MySQL 5.7;nginx
en el que se utilice el servicio app
para analizar el código PHP antes de proporcionar la aplicación Laravel al usuario final.Para permitir un proceso de desarrollo simplificado y facilitar la depuración de aplicaciones, mantendremos sincronizados los archivos de la aplicación usando volúmenes compartidos. También veremos cómo usar comandos docker-compose exec
para la ejecución de Composer y Artisan en el contenedor app
.
Para comenzar, obtendremos la aplicación Laravel de demostración de su repositorio de Github. Nos interesa la ramificación tutorial-01
, que contiene la aplicación básica de Laravel que creamos en la primera guía de esta serie.
Para obtener el código de la aplicación que es compatible con este tutorial, descargue la versión tutorial-1.0.1
en su directorio de inicio con lo siguiente:
cd ~
curl -L https://github.com/do-community/travellist-laravel-demo/archive/tutorial-1.0.1.zip -o travellist.zip
Necesitaremos el comando unzip
para desempaquetar el código de la aplicación. En caso de que no haya instalado el paquete antes, hágalo ahora con lo siguiente:
sudo apt update
sudo apt install unzip
Luego, descomprima el contenido de la aplicación y cambie el nombre del directorio desempaquetado para facilitar el acceso:
unzip travellist.zip
mv travellist-laravel-demo-tutorial-1.0.1 travellist-demo
Diríjase al directorio travellist-demo
:
cd travellist-demo
En el siguiente paso, crearemos un archivo de configuración .env
para configurar la aplicación.
.env
de la aplicaciónLos archivos de configuración de Laravel se encuentran en un directorio llamado config
, dentro del directorio root de la aplicación. Además, un archivo .env
se utiliza para establecer una configuración dependiente del entorno, como las credenciales y cualquier información que pueda variar entre las implementaciones. Este archivo no está incluido en el control de revisiones.
Advertencia: En el archivo de configuración del entorno se encuentra información confidencial sobre su servidor, incluidas las credenciales de bases de datos y las claves de seguridad. Por ese motivo, nunca debe compartir públicamente este archivo.
Los valores incluidos en el archivo .env
tendrán prioridad sobre los valores establecidos en los archivos de configuración normales que se encuentran en el directorio config
. Para cada instalación en un nuevo entorno se requiere un archivo de entorno personalizado a fin de definir elementos como las configuraciones de conexión de bases de datos, las opciones de depuración y las URL de aplicación, entre otros elementos que pueden variar dependiendo del entorno en el que se ejecute la aplicación.
Ahora, crearemos un nuevo archivo .env
para personalizar las opciones de configuración para el entorno de desarrollo que configuraremos. En Laravel se incluye un archivo .env
de ejemplo que podemos copiar para crear el nuestro:
cp .env.example .env
Abra este archivo utilzando nano
o el editor de texto que prefiera:
nano .env
En el archivo .env
actual de la aplicación de demostración travellist
se incluyen las configuraciones para usar una base de datos local de MySQL, con 127.0.0.1
como host de base de datos. Necesitamos actualizar la variable DB_HOST
para que esta apunte al servicio de base de datos que crearemos en nuestro entorno de Docker. En esta guía, usaremos el nombre db
para el servicio de nuestra base de datos. Sustituya el valor de la lista de DB_HOST
por el nombre del servicio de la base de datos:
.env
APP_NAME=Travellist
APP_ENV=dev
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost:8000
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=travellist
DB_USERNAME=travellist_user
DB_PASSWORD=password
...
Si lo desea, puede cambiar también el nombre, el nombre de usuario y la contraseña de la base de datos. Estas variables aprovecharán en un paso posterior en el que prepararemos el archivo docker-compose.yml
para configurar nuestros servicios.
Guarde el archivo cuando finalice la edición. Si utiliza nano
, puede hacerlo presionando Ctrl+x
, luego Y
y Enter
para confirmar.
#laravel #y
1651078800
¡Hola a todos! En este artículo hablaremos sobre la memorización, una técnica de optimización que puede ayudar a que los procesos de cómputo pesado sean más eficientes.
Comenzaremos hablando de qué es la memoización y cuándo es mejor implementarla. Más adelante daremos ejemplos prácticos para JavaScript y React.
¿Qué es Memoización?
En programación, la memorización es una técnica de optimización que hace que las aplicaciones sean más eficientes y, por lo tanto, más rápidas. Para ello, almacena los resultados de los cálculos en la memoria caché y recupera esa misma información de la memoria caché la próxima vez que se necesita en lugar de volver a calcularla.
En palabras más simples, consiste en almacenar en caché la salida de una función y hacer que la función verifique si cada cálculo requerido está en el caché antes de calcularlo.
Un caché es simplemente un almacén de datos temporal que contiene datos para que las futuras solicitudes de esos datos se puedan atender más rápido.
La memorización es un truco simple pero poderoso que puede ayudar a acelerar nuestro código, especialmente cuando se trata de funciones informáticas repetitivas y pesadas.
¿Cómo funciona la memorización?
El concepto de memorización en JavaScript se basa en dos conceptos:
Ejemplo de memorización de JavaScript
Para aclarar este galimatías, usaremos el ejemplo clásico de la sucesión de Fibonacci.
La sucesión de Fibonacci es un conjunto de números que comienza con un uno o un cero, seguido de un uno, y se basa en la regla de que cada número (llamado número de Fibonacci) es igual a la suma de los dos números anteriores.
Se parece a esto:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, …
Digamos que necesitamos escribir una función que devuelva el n-ésimo elemento en la secuencia de Fibonacci. Sabiendo que cada elemento es la suma de los dos anteriores, una solución recursiva podría ser la siguiente:
const fib = n => {
if (n <= 1) return 1
return fib(n - 1) + fib(n - 2)
}
Si no está familiarizado con la recursividad, es simplemente el concepto de una función que se llama a sí misma, con algún tipo de caso base para evitar un bucle infinito (en nuestro caso if (n <= 1)
).
Si llamamos a nuestra función como fib(5)
, detrás de escena nuestra función se ejecutaría así:
Ver que estamos ejecutando fib(0), fib(1), fib(2) and fib(3)
varias veces. Bueno, ese es exactamente el tipo de problema que la memorización ayuda a resolver.
Con la memorización, no hay necesidad de volver a calcular los mismos valores una y otra vez; simplemente almacenamos cada cálculo y devolvemos el mismo valor cuando sea necesario nuevamente.
Implementando la memorización, nuestra función se vería así:
const fib = (n, memo) => {
memo = memo || {}
if (memo[n]) return memo[n]
if (n <= 1) return 1
return memo[n] = fib(n-1, memo) + fib(n-2, memo)
}
Lo que estamos haciendo primero es comprobar si hemos recibido el objeto memo como parámetro. Si no lo hicimos, lo configuramos para que sea un objeto vacío:
memo = memo || {}
Luego, verificamos si memo contiene el valor que estamos recibiendo como parámetro dentro de sus claves. Si es así, lo devolvemos. Aquí es donde ocurre la magia. No hay necesidad de más recursividad una vez que tenemos nuestro valor almacenado en memo. =)
if (memo[n]) return memo[n]
Si aún no tenemos el valor en memo, llamamos fib nuevamente, pero ahora pasamos memo como parámetro, por lo que las funciones que llamamos compartirán los mismos valores memorizados que tenemos en la función "original". Tenga en cuenta que agregamos el resultado final al caché antes de devolverlo.
return memo[n] = fib(n-1, memo) + fib(n-2, memo)
¡Y eso es! ¡Con dos líneas de código hemos implementado la memorización y mejorado significativamente el rendimiento de nuestra función!
Ejemplo de memorización de reacción
En React, podemos optimizar nuestra aplicación evitando la repetición innecesaria de componentes mediante la memorización.
Como mencioné también en este otro artículo sobre la gestión del estado en React , los componentes se vuelven a renderizar debido a dos cosas: un cambio en el estado o un cambio en los accesorios . Esta es precisamente la información que podemos "cachear" para evitar renderizaciones innecesarias.
Pero antes de que podamos saltar al código, introduzcamos algunos conceptos importantes.
React admite componentes de clase o funcionales. Un componente funcional es una función simple de JavaScript que devuelve JSX, y un componente de clase es una clase de JavaScript que amplía React.Component y devuelve JSX dentro de un método de representación.
¿Y qué es entonces un componente puro? Bien, basándonos en el concepto de pureza en los paradigmas de programación funcional, se dice que una función es pura si:
De la misma manera, un componente de React se considera puro si genera el mismo resultado para el mismo estado y accesorios.
Un componente puro funcional podría verse así:
// Pure component
export default function PureComponent({name, lastName}) {
return (
<div>My name is {name} {lastName}</div>
)
}
Vea que pasamos dos accesorios, y el componente representa esos dos accesorios. Si los accesorios son los mismos, el render siempre será el mismo.
Por otro lado, digamos, por ejemplo, que agregamos un número aleatorio a cada accesorio antes de renderizar. Entonces, la salida podría ser diferente incluso si los accesorios siguen siendo los mismos, por lo que sería un componente impuro.
// Impure component
export default function ImpurePureComponent({name, lastName}) {
return (
<div>My "impure" name is {name + Math.random()} {lastName + Math.random()}</div>
)
}
Los mismos ejemplos con componentes de clase serían:
// Pure component
class PureComponent extends React.Component {
render() {
return (
<div>My "name is {this.props.name} {this.props.lastName}</div>
)
}
}
export default PureComponent
// Impure component
class ImpurePureComponent extends React.Component {
render() {
return (
<div>My "impure" name is {this.props.name + Math.random()} {this.props.lastName + Math.random()}</div>
)
}
}
export default ImpurePureComponent
Para componentes puros de clase , para implementar la memorización, React proporciona la PureComponent
clase base.
Los componentes de clase que amplían la React.PureComponent
clase tienen algunas mejoras de rendimiento y optimizaciones de representación. Esto se debe a que React implementa el shouldComponentUpdate()
método para ellos con una comparación superficial de props y state .
Veámoslo en un ejemplo. Aquí tenemos un componente de clase que es un contador, con botones para cambiar ese contador sumando o restando números. También tenemos un componente secundario al que le estamos pasando un nombre de propiedad que es una cadena.
import React from "react"
import Child from "./child"
class Counter extends React.Component {
constructor(props) {
super(props)
this.state = { count: 0 }
}
handleIncrement = () => { this.setState(prevState => {
return { count: prevState.count - 1 };
})
}
handleDecrement = () => { this.setState(prevState => {
return { count: prevState.count + 1 };
})
}
render() {
console.log("Parent render")
return (
<div className="App">
<button onClick={this.handleIncrement}>Increment</button>
<button onClick={this.handleDecrement}>Decrement</button>
<h2>{this.state.count}</h2>
<Child name={"Skinny Jack"} />
</div>
)
}
}
export default Counter
El componente secundario es un componente puro que solo representa el accesorio recibido.
import React from "react"
class Child extends React.Component {
render() {
console.log("Skinny Jack")
return (
<h2>{this.props.name}</h2>
)
}
}
export default Child
Tenga en cuenta que hemos agregado console.logs a ambos componentes para que recibamos mensajes de la consola cada vez que se procesan. Y hablando de eso, ¿adivinen qué sucede cuando presionamos los botones de incremento o decremento? Nuestra consola se verá así:
El componente secundario se vuelve a renderizar incluso si siempre recibe la misma propiedad.
Para implementar la memorización y optimizar esta situación, necesitamos extender la React.PureComponent
clase en nuestro componente hijo, así:
import React from "react"
class Child extends React.PureComponent {
render() {
console.log("Skinny Jack")
return (
<h2>{this.props.name}</h2>
)
}
}
export default Child
Después de eso, si presionamos el botón de incrementar o decrementar, nuestra consola se verá así:
Solo la renderización inicial del componente secundario y no se vuelven a renderizar innecesariamente cuando el accesorio no ha cambiado. Pedazo de pastel. ;)
Con esto hemos cubierto los componentes de la clase, pero en los componentes funcionales no podemos extender la React.PureComponent
clase. En cambio, React ofrece un HOC y dos ganchos para lidiar con la memorización.
Si transformamos nuestro ejemplo anterior a componentes funcionales obtendríamos lo siguiente:
import { useState } from 'react'
import Child from "./child"
export default function Counter() {
const [count, setCount] = useState(0)
const handleIncrement = () => setCount(count+1)
const handleDecrement = () => setCount(count-1)
return (
<div className="App">
{console.log('parent')}
<button onClick={() => handleIncrement()}>Increment</button>
<button onClick={() => handleDecrement()}>Decrement</button>
<h2>{count}</h2>
<Child name={"Skinny Jack"} />
</div>
)
}
import React from 'react'
export default function Child({name}) {
console.log("Skinny Jack")
return (
<div>{name}</div>
)
}
Esto provocaría el mismo problema que antes, si el componente Child se volviera a renderizar innecesariamente. Para resolverlo, podemos envolver nuestro componente secundario en el memo
componente de orden superior, como sigue:
import React from 'react'
export default React.memo(function Child({name}) {
console.log("Skinny Jack")
return (
<div>{name}</div>
)
})
Un componente de orden superior o HOC es similar a una función de orden superior en javascript. Las funciones de orden superior son funciones que toman otras funciones como argumentos O devuelven otras funciones. Los HOC de React toman un componente como accesorio y lo manipulan hasta cierto punto sin cambiar el componente en sí. Puede pensar en esto como componentes de envoltura.
En este caso, memo
hace un trabajo similar a PureComponent
, evitando renderizaciones innecesarias de los componentes que envuelve.
Una cosa importante a mencionar es que memo no funciona si el accesorio que se pasa al componente es una función. Refactoricemos nuestro ejemplo para ver esto:
import { useState } from 'react'
import Child from "./child"
export default function Counter() {
const [count, setCount] = useState(0)
const handleIncrement = () => setCount(count+1)
const handleDecrement = () => setCount(count-1)
return (
<div className="App">
{console.log('parent')}
<button onClick={() => handleIncrement()}>Increment</button>
<button onClick={() => handleDecrement()}>Decrement</button>
<h2>{count}</h2>
<Child name={console.log('Really Skinny Jack')} />
</div>
)
}
import React from 'react'
export default React.memo(function Child({name}) {
console.log("Skinny Jack")
return (
<>
{name()}
<div>Really Skinny Jack</div>
</>
)
})
Ahora nuestro accesorio es una función que siempre registra la misma cadena, y nuestra consola volverá a verse así:
Esto se debe a que, en realidad, se está creando una nueva función en cada renderización del componente principal. Entonces, si se está creando una nueva función, eso significa que tenemos un nuevo accesorio y eso significa que nuestro componente secundario también debería volver a renderizarse.
Para lidiar con este problema, reaccionar proporciona el enlace useCallback . Podemos implementarlo de la siguiente manera:
import { useState, useCallback } from 'react'
import Child from "./child"
export default function Counter() {
const [count, setCount] = useState(0)
const handleIncrement = () => setCount(count+1)
const handleDecrement = () => setCount(count-1)
return (
<div className="App">
{console.log('parent')}
<button onClick={() => handleIncrement()}>Increment</button>
<button onClick={() => handleDecrement()}>Decrement</button>
<h2>{count}</h2>
<Child name={ useCallback(() => {console.log('Really Skinny Jack')}, []) } />
</div>
)
}
Y eso resuelve el problema de la reproducción innecesaria de niños.
Lo que hace useCallback es mantener el valor de la función a pesar de que el componente principal se vuelve a renderizar, por lo que la propiedad secundaria seguirá siendo la misma siempre que el valor de la función también sea el mismo.
Para usarlo, solo necesitamos envolver el enlace useCallback alrededor de la función que estamos declarando. En la matriz presente en el gancho, podemos declarar variables que activarían el cambio del valor de la función cuando la variable también cambia (exactamente de la misma manera que funciona useEffect).
const testingTheTest = useCallback(() => {
console.log("Tested");
}, [a, b, c]);
useMemo es un gancho muy similar a useCallback, pero en lugar de almacenar en caché una función, useMemo almacenará en caché el valor de retorno de una función
norte _
En este ejemplo, useMemo
almacenará en caché el número 2
.
const num = 1
const answer = useMemo(() => num + 1, [num])
Mientras useCallback
se almacenará en caché () => num + 1
.
const num = 1
const answer = useMemo(() => num + 1, [num])
Puede usar useMemo de una manera muy similar al memo HOC. La diferencia es que useMemo es un enlace con una serie de dependencias, y memo es un HOC que acepta como parámetro una función opcional que usa accesorios para actualizar condicionalmente el componente.
Además, useMemo almacena en caché un valor devuelto entre renderizaciones, mientras que memo almacena en caché un componente de reacción completo entre renderizaciones.
La memorización en React es una buena herramienta para tener en el cinturón, pero no es algo que debas usar en todas partes. Estas herramientas son útiles para manejar funciones o tareas que requieren mucho cálculo.
Tenemos que ser conscientes de que, en el fondo, estas tres soluciones también agregan sobrecarga a nuestro código. Por lo tanto, si el re-renderizado es causado por tareas que no son computacionalmente pesadas, puede ser mejor resolverlo de otra manera o dejarlo solo.
Recomiendo este artículo de Kent C. Dodds para obtener más información sobre este tema.
Redondeo
Eso es todo, todos! Como siempre, espero que hayas disfrutado el artículo y hayas aprendido algo nuevo. Si quieres, también puedes seguirme en LinkedIn o Twitter .
¡Salud y nos vemos en la próxima! =D
Fuente: https://www.freecodecamp.org/news/memoization-in-javascript-and-react/
1656145200
El selector de CSS :has()
nos permite diseñar un elemento en función de sus descendientes o cualquier elemento posterior. En este tutorial, repasaremos cuándo y cómo usar el :has()
selector.
:has()
Por lo general, cuando escribimos reglas CSS que apuntan a elementos HTML, el motor del navegador evalúa las reglas de derecha a izquierda para aplicarlas. Por ejemplo, la siguiente regla CSS apunta al <p>
elemento dentro de <section>
:
section p {
color: red;
}
Ahora, supongamos que queremos apuntar a un elemento en función de su contenido o elementos posteriores; por ejemplo, apuntar a un <section>
elemento que contiene un <p>
elemento. Normalmente, agregaríamos clases CSS manualmente para diseñar y modificar el elemento de destino.
Otro escenario implica apuntar a los hermanos anteriores de un elemento, como una etiqueta de formulario que precede a una entrada válida o no válida.
En este caso, diseñar la etiqueta implicaría escribir más reglas CSS de las que normalmente se necesitan. A veces, es posible que necesitemos que JavaScript se dirija a los elementos anteriores en función del estado de ciertos elementos.
Sin embargo, con el :has()
selector de pseudoclase, podemos lograr todas las tareas anteriores con CSS de manera más limpia, clara y concisa.
:has()
selector de CSSAntes de profundizar más, echemos un vistazo a qué navegadores son compatibles con el :has
selector CSS :
Por el momento, el :has()
selector de CSS solo está habilitado de forma predeterminada en la última versión de Safari. Otros navegadores aún tienen que habilitar el soporte para él.
Sin embargo, en las últimas versiones de Chrome, podemos habilitar :has()
la compatibilidad con CSS a través del indicador de funciones experimentales. Por el bien de este tutorial, comenzaremos con eso.
:has()
compatibilidad con CSS en ChromePara aquellos de nosotros que no usamos Safari, abramos el navegador Chrome y visitemos la lista de funciones experimentales de Chrome escribiendo lo siguiente en su navegador: chrome://flags/
Luego, busque "características experimentales de la plataforma web" y habilite esta bandera, como se muestra en la imagen a continuación:
Después de habilitar las funciones experimentales de la plataforma web, reinicie el navegador para activarlas.
:has()
La :has()
pseudoclase acepta una lista de selectores de CSS como argumentos:
<target>:has(<selector>)
Al igual que otras pseudoclases de CSS , la lista de selectores es "perdonadora". En otras palabras, CSS :has
ignora los selectores no válidos que se pasan como argumentos.
:has()
Familiaricémonos con cómo usar CSS :has()
antes de aplicar este selector a escenarios del mundo real. Revisaremos el ejemplo de la regla de estilo que usamos anteriormente para ver cómo :has()
nos permite apuntar a un elemento principal.
Con la siguiente regla usando el :has()
selector, apuntamos a un <section>
elemento que tiene un <p>
elemento como hijo:
section:has(p) {
color: red
}
En la regla anterior, vemos que section
es el elemento de destino al que se color: red
aplica el estilo, pero solo si contiene un p
elemento.
:has()
Hasta ahora, solo hemos pasado selectores simples como argumentos en :has()
. No obstante, también podemos utilizar selectores de CSS más avanzados .
Por ejemplo, también podemos pasar algunos selectores combinadores regulares como argumentos. A continuación, el siguiente selector coincide con el h2
elemento que tiene elementos de párrafo como hermanos:
h2:has(+ p) {
color: yellow;
}
A diferencia de un simple selector de CSS, h2 + p
coincidirá con los p
elementos que siguen inmediatamente a un h2
.
Debemos comprender cómo funcionan los selectores de combinadores al pasarlos como argumentos en :has()
. Echemos un vistazo a un par de ejemplos más.
En el siguiente código, el selector coincide con los elementos de la lista que tienen un párrafo seguido de otro párrafo:
li:has(p + p) {
color: grey;
}
El selector a continuación coincide con los p
elementos que contienen directamente un span
hijo:
p:has(> span) {
color: blue;
}
:has()
con la :not()
pseudo-claseA veces, es posible que queramos apuntar a elementos que no coincidan con ciertos selectores. En este caso, podemos usar el :has()
selector con :not()
pseudo-clase . En el siguiente ejemplo, la regla apunta a li
elementos que no contienen ningún párrafo:
li:not(:has(p)) {
font-weight: 700;
}
También podemos pasar múltiples selectores como argumentos. A continuación, la regla apunta a li
elementos que no contienen ningún párrafo o span
elemento:
li:not(:has(p, span)) {
font-weight: 700;
}
:has()
A veces, podemos experimentar problemas con reglas en conflicto mientras usamos el :has()
selector. Saber cómo CSS maneja la especificidad de su selector general puede ayudarlo a resolver problemas con reglas de CSS en conflicto .
Echemos un vistazo a los siguientes bloques de código:
Estos son los elementos HTML que estamos diseñando:
<ul>
<!-- other items -->
<li>
<h3 id="h3">Heading III</h3> <!-- blue color -->
<p class="cls">paragraph</p> <!-- blue color -->
</li>
</ul>
Aquí están nuestras reglas de estilo en CSS:
li:has(p, #h3) {
color: blue; /* this declaration is applied */
}
li:has(p.cls) {
color: green;
}
Podemos esperar que la regla de estilo que viene en último lugar en la cascada se aplique al p
elemento. Pero en realidad, en este ejemplo, se aplica la primera regla.
Esto se debe a la especificidad en CSS: el :has()
selector se remite a su argumento más específico. En la regla anterior, el #h3
es el más específico, lo que hace que el navegador también aplique su declaración de estilo al p
elemento.
:has()
selector CSSPara comprender cómo implementar la :has()
pseudoclase en un proyecto del mundo real, consideremos los siguientes casos de uso.
El diseño a continuación es común en sitios web que muestran planes de precios. Observe que la tarjeta "recomendada" tiene un estilo diferente y se amplía para llamar más la atención:
Podemos lograr esto fácilmente usando el :has()
selector.
A continuación se muestra el marcado HTML para las tarjetas. Aplicaremos un estilo recommend
diferente a la tarjeta que contiene una clase anidada:
<section class="card-container">
<div class="pricing-card">
<!-- card content -->
</div>
<div class="pricing-card">
<div class="recommend">Recommended</div>
<!-- card content -->
</div>
<div class="pricing-card">
<!-- card content -->
</div>
</section>
Tenga en cuenta que eliminamos el contenido de la tarjeta en el código anterior por brevedad. Vea el marcado completo en CodePen .
Luego, con los estilos básicos, las tarjetas se ven así:
Con el :has()
selector, podemos apuntar y diseñar la tarjeta que solo tiene la recommend
clase como elemento secundario:
.pricing-card:has(div.recommend) {
box-shadow: 0 0 0 2px #4b4bf0, 0 1rem 2rem rgba(0, 0, 0, 0.1);
transform: scale(1.1);
z-index: 1;
}
La regla anterior apunta a la tarjeta recomendada y la escala según lo previsto al mismo tiempo que le aplica una sombra paralela.
Si quisiéramos lograr este diseño sin usar el :has()
selector, tendríamos que aplicar manualmente una clase separada en el contenedor de tarjetas "recomendado" para darle un estilo diferente. La desventaja aquí es que tendríamos que agregar la clase en cada sección que use el mismo diseño.
Vamonos. Si echamos un vistazo al proyecto final, el botón "Comprar ahora" de la tarjeta recomendada también tiene un estilo diferente al de las otras dos tarjetas. Para lograr esto, usaremos :not()
junto al :has()
selector, así:
.pricing-card:not(:has(.recommend)) a {
color: #000;
background: #d5ddeb;
}
En el código anterior, estamos apuntando a los botones dentro de las tarjetas que no tienen la recommend
clase como elemento secundario para darles texto y fondos de diferentes colores.
En nuestro siguiente ejemplo, diseñaremos las etiquetas de entrada en función de la validez de sus entradas correspondientes. Nuestro resultado final se verá así:
Vamos a empezar. El siguiente código representa el control de formulario dentro de un form
elemento:
<form>
<div>
<label for="email">Email: </label>
<input type="email" id="email" required/>
</div>
<!-- other input -->
</form>
Tenga en cuenta que solo mostramos un contenedor de entrada en el código anterior por brevedad. Vea el marcado completo en CodePen .
Al igual que el proyecto anterior, veamos cómo orientaríamos las etiquetas de entrada sin usar el :has()
selector.
Recuerde, dijimos anteriormente que los navegadores normalmente evalúan las reglas de estilo desde la derecha. Por esta razón, podríamos colocar el label
después del input
elemento:
<div>
<input type="email" id="email" required/>
<label for="email">Email: </label>
</div>
Luego, podríamos usar el combinador de hermanos general ~
o adyacente para seleccionar y diseñar la etiqueta:+
input:invalid ~ label,
input:invalid ~ label::before {
content: ' ';
color: red;
}
input:valid ~ label,
input:valid ~ label::before {
content: '✓ ';
color: green;
}
Después de eso, usaríamos el CSS position: absolute;
para colocar las etiquetas nuevamente encima de la entrada:
form > div {
position: relative;
margin-bottom: 30px;
}
label {
position: absolute;
top: -30px;
left: 0;
right: 0;
}
Sin embargo, con el :has()
selector, no tenemos que colocar la etiqueta después de la entrada ni usar la position: absolute;
declaración CSS. Podemos apuntar fácilmente a los hermanos anteriores así:
label:has(+ input:invalid),
label:has(+ input:invalid)::before {
content: ' ';
color: red;
}
label:has(+ input:valid),
label:has(+ input:valid)::before {
content: '✓ ';
color: green;
}
En el primer y segundo bloque de código, nos dirigimos al label
que tiene una entrada no válida y una entrada válida como hermanos siguientes, respectivamente.
Como podemos ver, usar el :has()
selector hace que nuestro código sea más claro y breve. Ver el código completo en CodePen .
En este tutorial, aprendimos cómo el :has()
selector nos permite aplicar estilo a un elemento en función de sus descendientes o elementos posteriores mediante ejemplos prácticos. Este selector abre muchas posibilidades que hubieran sido difíciles de conseguir en CSS.
Actualmente, el selector de CSS :has()
no es ampliamente compatible con los navegadores; este selector solo funciona en la última versión de Safari o mediante el indicador de características experimentales en la última versión de Chrome.
Entonces, por ahora, no debemos usar :has()
en producción. Solo podemos explorar cómo funciona mientras esperamos que otros navegadores lo admitan.
Espero que hayas disfrutado leyendo este tutorial. Si tiene preguntas o contribuciones, comparta sus pensamientos en la sección de comentarios y recuerde compartir esta publicación en la web.
Fuente: https://blog.logrocket.com/how-when-use-css-has-selector/