react practicas organizar mejores funcionales estado entre entender ejemplos comunicacion componentes component como javascript reactjs ecmascript-6

javascript - practicas - Reaccionar componente funcional sin estado, Componente puro, Componente; ¿Cuáles son las diferencias y cuándo debemos usar qué?



react comunicacion entre componentes (3)

¿Cómo decide, cómo elige entre estos tres en función del propósito / tamaño / accesorios / comportamiento de nuestros componentes?

Extender desde React.PureComponent o desde React.Component con un método shouldComponentUpdate personalizado tiene implicaciones de rendimiento. El uso de componentes funcionales sin estado es una opción "arquitectónica" y aún no tiene beneficios de rendimiento listos para usar.

  • Para componentes simples, solo presentacionales que necesitan ser reutilizados fácilmente, prefiera componentes funcionales sin estado. De esta manera, está seguro de que están desconectados de la lógica de la aplicación real, que son fáciles de probar y que no tienen efectos secundarios inesperados. La excepción es si por alguna razón tiene muchos de ellos o si realmente necesita optimizar su método de representación (ya que no puede definir shouldComponentUpdate para un componente funcional sin estado).

  • Extienda PureComponent si sabe que su salida depende de accesorios / estado simples ("simple" significa que no hay estructuras de datos anidadas, ya que PureComponent realiza una comparación superficial) Y necesita / puede obtener algunas mejoras de rendimiento.

  • Extienda el Component e implemente su propio shouldComponentUpdate si necesita algunas mejoras de rendimiento al realizar una lógica de comparación personalizada entre los accesorios y el estado siguiente / actual. Por ejemplo, puede realizar rápidamente una comparación profunda usando lodash # isEqual:

    class MyComponent extends Component { shouldComponentUpdate (nextProps, nextState) { return !_.isEqual(this.props, nextProps) || !_.isEqual(this.state, nextState); } }

Además, implementar su propia shouldComponentUpdate o extenderse desde PureComponent son optimizaciones, y como de costumbre, debe comenzar a investigar eso solo si tiene problemas de rendimiento ( evite optimizaciones prematuras ). Como regla general, siempre trato de hacer estas optimizaciones después de que la aplicación está funcionando, con la mayoría de las características ya implementadas. Es mucho más fácil concentrarse en los problemas de rendimiento cuando realmente se interponen en el camino.

Más detalles

Componentes sin estado funcionales:

Estos se definen simplemente usando una función. Como no hay un estado interno para un componente sin estado, la salida (lo que se procesa) solo depende de los accesorios proporcionados como entrada para esta función.

Pros:

  • La forma más simple posible de definir un componente en React. Si no necesita administrar ningún estado, ¿por qué molestarse con las clases y la herencia? Una de las principales diferencias entre una función y una clase es que con la función está seguro de que la salida depende solo de la entrada (no de ningún historial de ejecuciones anteriores).

  • Idealmente en su aplicación, debe intentar tener tantos componentes sin estado como sea posible, porque eso normalmente significa que movió su lógica fuera de la capa de vista y la movió a algo como redux, lo que significa que puede probar su lógica real sin tener que renderizar nada (mucho más fácil de probar, más reutilizable, etc.).

Contras:

  • No hay métodos de ciclo de vida. No tiene una manera de definir componentDidMount y otros amigos. Normalmente lo haces dentro de un componente padre más alto en la jerarquía para que puedas convertir a todos los hijos en apátridas.

  • No hay forma de controlar manualmente cuando se necesita una nueva representación, ya que no puede definir shouldComponentUpdate . Un renderizado ocurre cada vez que el componente recibe nuevos accesorios (no hay forma de comparar superficialmente, etc.). En el futuro, React podría optimizar automáticamente los componentes sin estado, por ahora hay algunas bibliotecas que puede usar. Dado que los componentes sin estado son solo funciones, básicamente es el problema clásico de la "memorización de funciones".

  • Las referencias no son compatibles: https://github.com/facebook/react/issues/4936

Un componente que extiende la clase PureComponent VS Un componente normal que extiende la clase Componente:

React solía tener un PureRenderMixin que podía adjuntar a una clase definida usando la sintaxis React.createClass . El mixin simplemente definiría un shouldComponentUpdate realizando una comparación superficial entre los siguientes accesorios y el siguiente estado para verificar si algo ha cambiado. Si nada cambia, entonces no hay necesidad de realizar una nueva representación.

Si desea usar la sintaxis de ES6, no puede usar mixins. Entonces, por conveniencia, React introdujo una clase PureComponent la que puede heredar en lugar de usar Component . PureComponent solo implementa shouldComponentUpdate de la misma manera que PureRendererMixin . Es principalmente una cuestión de conveniencia, por lo que no tiene que implementarlo usted mismo, ya que una comparación superficial entre el estado actual / próximo y los accesorios es probablemente el escenario más común que puede darle algunas ganancias rápidas de rendimiento.

Ejemplo:

class UserAvatar extends Component { render() { return <div><img src={this.props.imageUrl} /> {{ this.props.username }} </div> } }

Como puede ver, la salida depende de props.imageUrl y props.username . Si en un componente principal representa <UserAvatar username="fabio" imageUrl="http://foo.com/fabio.jpg" /> con los mismos accesorios, React llamará a render cada vez, incluso si el resultado fuera exactamente lo mismo. Sin embargo, recuerde que React implementa dom diffing, por lo que el DOM no se actualizaría realmente. Aún así, realizar la diferenciación de dom puede ser costoso, por lo que en este escenario sería un desperdicio.

Si el componente UserAvatar extiende PureComponent en PureComponent lugar, se realiza una comparación superficial. Y debido a que los accesorios y nextProps son iguales, no se llamará render en absoluto.

Notas sobre la definición de "puro" en React:

En general, una "función pura" es una función que evalúa siempre el mismo resultado dada la misma entrada. La salida (para React, eso es lo que devuelve el método de render ) no depende de ningún historial / estado y no tiene ningún efecto secundario (operaciones que cambian el "mundo" fuera de la función).

En React, los componentes sin estado no son necesariamente componentes puros de acuerdo con la definición anterior si llama "sin estado" a un componente que nunca llama this.setState y que no usa this.state .

De hecho, en un PureComponent , aún puede realizar efectos secundarios durante los métodos del ciclo de vida. Por ejemplo, podría enviar una solicitud ajax dentro de componentDidMount o podría realizar algunos cálculos DOM para ajustar dinámicamente la altura de un div dentro del render .

La definición de "Componentes tontos" tiene un significado más "práctico" (al menos en mi entendimiento): un componente tonto "se le dice" qué hacer por un componente padre a través de accesorios, y no sabe cómo hacer las cosas, pero usa accesorios devoluciones de llamada en su lugar.

Ejemplo de un AvatarComponent "inteligente":

class AvatarComponent extends Component { expandAvatar () { this.setState({ loading: true }); sendAjaxRequest(...).then(() => { this.setState({ loading: false }); }); } render () { <div onClick={this.expandAvatar}> <img src={this.props.username} /> </div> } }

Ejemplo de un AvatarComponent "tonto":

class AvatarComponent extends Component { render () { <div onClick={this.props.onExpandAvatar}> {this.props.loading && <div className="spinner" />} <img src={this.props.username} /> </div> } }

Al final, diría que "tonto", "sin estado" y "puro" son conceptos muy diferentes que a veces pueden superponerse, pero no necesariamente, dependiendo principalmente de su caso de uso.

Llegué a saber que desde React v15.3.0 , tenemos una nueva clase base llamada PureComponent para extender con PureRenderMixin incorporado. Lo que entiendo es que, bajo el capó, esto emplea una comparación superficial de accesorios dentro de shouldComponentUpdate .

Ahora tenemos 3 formas de definir un componente Reaccionar:

  1. Componente sin estado funcional que no extiende ninguna clase
  2. Un componente que extiende la clase PureComponent
  3. Un componente normal que extiende la clase Component

Hace algún tiempo, solíamos llamar a componentes sin estado como Componentes Puros, o incluso Componentes Dumb. Parece que toda la definición de la palabra "puro" ahora ha cambiado en React.

Aunque entiendo las diferencias básicas entre estos tres, todavía no estoy seguro de cuándo elegir qué . ¿Cuáles son los impactos en el rendimiento y las compensaciones de cada uno?

Actualización :

Estas son las preguntas que espero aclarar:

  • ¿Debo elegir definir mis componentes simples como funcionales (en aras de la simplicidad) o extender la clase PureComponent (en aras del rendimiento)?
  • ¿Es el aumento de rendimiento que obtengo una verdadera compensación por la simplicidad que perdí?
  • ¿Alguna vez necesitaría extender la clase de Component normal cuando siempre puedo usar PureComponent para un mejor rendimiento?

No soy un genio sobre reaccionar, pero según tengo entendido, podemos usar cada componente en las siguientes situaciones

  1. Componente sin estado: este es el componente que no tiene ciclo de vida, por lo que esos componentes se deben usar para representar el elemento repetido del componente principal, como la lista de texto que solo muestra la información y no tiene que realizar ninguna acción.

  2. Componente puro: estos son los elementos que tienen un ciclo de vida y siempre devolverán el mismo resultado cuando se proporciona un conjunto específico de accesorios. Esos componentes se pueden usar cuando se muestra una lista de resultados o datos de un objeto específico que no tiene elementos secundarios complejos y se utilizan para realizar operaciones que solo se afectan a sí mismas. como mostrar una lista de tarjetas de usuario o una lista de tarjetas de productos (información básica del producto) y la única acción que el usuario puede realizar es hacer clic para ver la página de detalles o agregar al carrito.

  3. Componentes normales o componentes complejos: utilicé el término componente complejo porque generalmente son componentes de nivel de página y consisten en muchos componentes secundarios y dado que cada uno de los elementos secundarios puede comportarse de una manera única y única, por lo que no puede estar 100% seguro de que lo hará renderizar el mismo resultado en un estado dado. Como dije generalmente, estos deberían usarse como componentes del contenedor


  • React.Component es el componente "normal" predeterminado. Los declaras usando la palabra clave class y extends React.Component . Piense en ellos como una clase, con métodos de ciclos de vida, controladores de eventos y cualquier método.

  • React.PureComponent es un React.Component que implementa shouldComponentUpdate() con una función que realiza una comparación superficial de sus props y state . forceUpdate() usar forceUpdate() si sabe que el componente tiene accesorios o datos anidados de estado que cambiaron y desea volver a renderizar. Por lo tanto, no son excelentes si necesita componentes para volver a renderizar cuando las matrices u objetos que pasa como accesorios o configurados en su estado cambian.

  • Los componentes funcionales son aquellos que no tienen funciones de ciclo de vida. Supuestamente son apátridas, pero son tan agradables y limpios que ahora tenemos ganchos (desde React 16.8) para que aún pueda tener un estado. Así que supongo que son solo "componentes limpios".