¿Cuándo usar los componentes React basados ​​en la clase ES6 frente a los componentes funcionales ES6 React?

213

Después de pasar un tiempo aprendiendo React, entiendo la diferencia entre los dos paradigmas principales de crear componentes.

Mi pregunta es cuándo debo usar cuál y por qué. ¿Cuáles son los beneficios / compensaciones de uno sobre el otro?


Clases de ES6:

import React, { Component } from 'react';

export class MyComponent extends Component {
  render() {
    return (
      <div></div>
    );
  }
}

Funcional:

const MyComponent = (props) => {
    return (
      <div></div>
    );
}

Estoy pensando en funcional cada vez que no hay un estado para ser manipulado por ese componente, pero ¿es eso?

Supongo que si uso algún método de ciclo de vida, podría ser mejor ir con un componente basado en la clase.

omarjmh
fuente
77
Parece que ya sabes la respuesta.
Felix Kling
2
Si tiene un componente solo con el método de representación, puede convertirlo en forma funcional. Si necesita algo más que una función de representación sin estado, use clases
solo el
2
Para ser aún más conciso intente esto:const MyComponent = (props) => <div>...</div>
Viliam Simko
1
Nunca uso funcional si se puede evitar. Porque inevitablemente termino necesitando refactorizar a la clase en el futuro. Y luego, a menudo, es necesario refactorizarlo a funcional después de eso.
keithjgrant
En 2020, el enfoque correcto es usar componentes funcionales siempre que sea posible, porque son compatibles con ganchos, y los ganchos son (en términos de rendimiento y arquitectura) mejores que las alternativas.
polkovnikov.ph

Respuestas:

162

Tienes la idea correcta. Vaya con funcional si su componente no hace mucho más que tomar algunos accesorios y renderizar. Puede pensar en estas como funciones puras porque siempre se renderizarán y se comportarán de la misma manera, dados los mismos accesorios. Además, no les importan los métodos del ciclo de vida o tienen su propio estado interno.

Debido a que son livianos, escribir estos componentes simples como componentes funcionales es bastante estándar.

Si sus componentes necesitan más funcionalidad, como mantener el estado, use clases en su lugar.

Más información: https://facebook.github.io/react/docs/reusable-components.html#es6-classes


EDITAR : Gran parte de lo anterior era cierto, hasta la introducción de React Hooks.

  • componentDidUpdatese puede replicar con useEffect(fn), donde fnes la función que se ejecuta al volver a procesar.

  • componentDidMountLos métodos se pueden replicar con useEffect(fn, []), donde fnes la función que se ejecutará al volver a renderizar, y []es una matriz de objetos para los cuales se volverá a procesar el componente, si y solo si al menos uno ha cambiado de valor desde el renderizado anterior. Como no hay ninguno, se useEffect()ejecuta una vez, en el primer montaje.

  • statese puede replicar con useState(), cuyo valor de retorno se puede desestructurar a una referencia del estado y una función que puede establecer el estado (es decir, const [state, setState] = useState(initState)). Un ejemplo podría explicar esto más claramente:

const Counter = () => {
  const [count, setCount] = useState(0)

  const increment = () => { 
    setCount(count + 1);
  }

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>+</button>
    </div>
  )
}

default export Counter

Con respecto a la recomendación sobre cuándo usar la clase sobre los componentes funcionales, Facebook recomienda oficialmente usar componentes funcionales siempre que sea posible . Como un pequeño aparte, he escuchado a varias personas debatir sobre no usar componentes funcionales por razones de rendimiento, específicamente que

"Las funciones de manejo de eventos se redefinen por render en componentes funcionales"

Si bien es cierto, tenga en cuenta si sus componentes realmente se están procesando a una velocidad o volumen tales que esto valdría la pena preocuparse.

Si lo son, puede evitar la redefinición de las funciones con useCallbacky useMemoganchos. Sin embargo, tenga en cuenta que esto puede empeorar el rendimiento de su código (microscópicamente) .

Pero, sinceramente, nunca he oído hablar de redefinir las funciones como un cuello de botella en las aplicaciones React. Las optimizaciones prematuras son la raíz de todo mal; preocúpese por esto cuando sea un problema

Jeff Cousins
fuente
¿Qué pasa con la funcionalidad que no mantiene el estado, pero está estrechamente acoplada al componente, por ejemplo, determina algún atributo dinámico para el render?
Dennis
Este es el mejor artículo sobre la diferencia entre los dos tipos de componentes en React: code.tutsplus.com/tutorials/…
Arian Acosta
55
A partir de React 16.8, puede usar el estado en un componente funcional, a través del useStategancho.
Greg
A partir de React 16.8, puede hacer casi todo en componentes funcionales, y todos los efectos finalmente se pueden modularizar con un impacto mínimo en el rendimiento.
polkovnikov.ph
1
¿Dónde has encontrado la información donde Facebook officially recommends using functional components wherever possible?
johannchopin
40

Siempre trate de usar funciones sin estado (componentes funcionales) siempre que sea posible. Hay escenarios en los que necesitará usar una clase React normal:

  • El componente necesita mantener el estado
  • El componente se está volviendo a representar demasiado y debe controlarlo a través de shouldComponentUpdate
  • Necesitas un componente contenedor

ACTUALIZAR

Ahora hay una clase React llamada PureComponentque puede extender (en lugar de Component) que implementa la suya shouldComponentUpdateque se encarga de la comparación de accesorios poco profundos para usted. Lee mas

ffxsam
fuente
43
Always try to use stateless functions (functional components) whenever possible.He leído que diez personas dicen eso. Todavía ninguno de ellos dio una explicación de por qué.
Rotareti
25
In an ideal world, most of your components would be stateless functions because in the future we’ll also be able to make performance optimizations specific to these components by avoiding unnecessary checks and memory allocations. This is the recommended pattern, when possible.Más información: facebook.github.io/react/docs/…
Diogo Cardoso
2
@rotareti No sé si siente que recibió una respuesta a su pregunta, pero las funciones puras son mucho más simples de entender, probar y mantener. Dados los mismos parámetros, siempre representan lo mismo. Los componentes que mantienen el estado y cambian cuando ocurren eventos del ciclo de vida son más difíciles de entender. No quiere decir que a veces no se necesitan, pero espero que esté claro que si no se necesitan sus ventajas, todo lo que hacen es agregar repeticiones no deseadas y gastos generales sin beneficios.
door_number_three
También querrá crear una clase de Componente si tiene sus propias definiciones de controlador de eventos. De esa manera, puede vincular previamente esos controladores de eventos al componente en el constructor en lugar de crear una nueva función nueva en cada render. Tenga en cuenta que esto no es necesario si todos sus controladores de eventos provienen de accesorios.
Dobes Vandermeer
Tenga en cuenta que la recomendación de Facebook citada ya no existe (vea mi comentario más arriba).
Garrett
34

ACTUALIZACIÓN Marzo 2019

https://overreacted.io/how-are-function-components-different-from-classes/

ACTUALIZACIÓN Febrero 2019:

Con la introducción de ganchos React , parece que los equipos React quieren que usemos componentes funcionales siempre que sea posible (lo que sigue mejor la naturaleza funcional de JavaScript).

Su motivación:

1.) Its hard to reuse stateful logic between components
2.) Complex components become hard to understand
3.) Classes confuse both people and machines

Un componente funcional con ganchos puede hacer casi todo lo que un componente de clase puede hacer, sin ninguno de los inconvenientes mencionados anteriormente.

Recomiendo usarlos tan pronto como sea posible.

Respuesta original

Los componentes funcionales no son más livianos que los componentes basados ​​en clases, "funcionan exactamente como clases". - https://github.com/facebook/react/issues/5677#issuecomment-241190513

El enlace anterior está un poco anticuado, pero la documentación de React 16.7.0 dice que los componentes funcionales y de clase:

"son equivalentes desde el punto de vista de React". - https://reactjs.org/docs/components-and-props.html#stateless-functions

Esencialmente no hay diferencia entre un componente funcional y un componente de clase que solo implementa el método de renderizado, aparte de la sintaxis.

En el futuro (citando el enlace de arriba) "nosotros [Reaccionar] podríamos agregar tales optimizaciones".

Si está tratando de aumentar el rendimiento eliminando renders innecesarios, ambos enfoques brindan soporte. memopara componentes funcionales yPureComponent para clases.

- https://reactjs.org/docs/react-api.html#reactmemo

- https://reactjs.org/docs/react-api.html#reactpurecomponent

Realmente depende de ti. Si desea menos repetitivo, vaya funcional. Si te encanta la programación funcional y no te gustan las clases, hazlo funcional. Si desea coherencia entre todos los componentes en su base de código, vaya con clases. Si estás cansado de refactorizar de componentes funcionales a componentes basados ​​en clases cuando necesitas algo como state, ve con clases.

Galupuf
fuente
1
Creo que hacer que cada componente se extienda React.Component hace que el código sea más legible, especialmente para las personas nuevas. Es agradable cuando ves un componente creado de la misma manera cada vez. Como dijo @Galupuf, los componentes simples solo tienen un método llamado "render ()". También es bueno hacer que todo se extienda React.Component porque cuando desea comenzar a vincular "esto", tener estado, etc., no tiene que refactorizar todo, simplemente puede agregar lo que necesita.
jeffski13
10

A partir de React 16.8, el término Componentes funcionales sin estado es engañoso y debe evitarse porque ya no son apátridas ( React.SFC en desuso , Dan Abramov en React.SFC ), pueden tener un estado, pueden tener ganchos (que actúan como el métodos de ciclo de vida) también, se superponen más o menos con componentes de clase

Componentes basados ​​en clase

Componentes funcionales:

¿Por qué prefiero los componentes funcionales?

  • React proporciona el gancho useEffect, que es una forma muy clara y concisa de combinar el componentDidMount, componentDidUpdateycomponentWillUnmount métodos del ciclo de vida
  • Con los ganchos puede extraer la lógica que se puede compartir fácilmente entre los componentes y probar
  • menos confusión sobre el alcance

Reaccione la motivación sobre por qué usar ganchos (es decir, componentes funcionales)

Karim
fuente