TIL: Diferencia de comportamiento entre un class component y un function component en React

TIL: Diferencia de comportamiento entre un class component y un function component en React

enmanuelm19@gmail.com2020-08-27 16:44:14 UTC

Today I Learn: Diferencia de comportamiento entre un class y function component en React

Recientemente tuve un pequeño problema manejando una llamada asincrona al servidor para llenar de datos un componente, y tratando de ver que pasaba y buscando por la solución, aprendi la diferencia de como se comporta el componentDidMount y useEffect(function, []).

Primero ver que en un class component la actualización del DOM es manejada a través de un ciclo de vida, con esto por ejemplo quiero indicar que si se realiza una llamada asincrona en el componentDidMount, al inicializarse el componente este imprime en el DOM lo que esta en el metodo reservado render y React es suficientemente inteligente para darse cuenta de la actualización durante el componentDidMount y renderiza este en el DOM en vez de la montura inicial, por lo tanto, visualmente no vemos una actualización de la interfaz.

En cambio cuando manejamos estados dentro de un function component, este se monta dentro del DOM al inicializarse, cuando se procesa el efecto a través de useEffect basicamente este vuelve a renderizar el DOM, y es visible el cambio en la interfaz. (Claro si la data a cargar es poca posiblemente no se note)

Ahora una manera de notar con claridad las diferencias de acceso al estado del componente por parte de un class component y un function component es imprimir en consola los valores de estos en la función asincrona, pero antes de que la función se resuelta setear algun valor en el state del componente:

De manera de demostrar visualmente esto aca dejo un snippet que pueden probar por su cuenta.

// Class Component
class ClassComponent extends React.Component {
  constructor() {
    super();
    this.state = { name: '' }
  }

  asyncFunction() {
    setTimeout(() => {
      console.log("Class state: ", this.state.name);
    }, 5000);
  }

  componentDidMount() {
    this.asyncFunction();
  }

  render() {
    return (
      <div>
        <p> Este es el class component </p>
        <button type="button" onClick={() => this.setState({ name: 'Hola' })}>Click para setear el name state</button>
        <p>{ this.state.name } </p>
      </div>
    )
  }
}
// Imprime "Class state: Hola" al resolverse la función asincrona
// Function component
const FunctionComponent = () => {
  const [name, setName] = useState('')

  const asyncFunction = () => {
    setTimeout(() => {
      console.log("Function state: ", name);
    }, 5000)
  }

  useEffect(() => {
    asyncFunction();
  }, [])

  return (
    <div>
      <p> Este es el function component </p>
      <p> { name } </p>
      <button type="button" onClick={() => setName('hola')}>Click setear name</button>
    </div>
  )
}
//Imprime "Function state: " un string vacio, debido a que el scope es de un componente que no esta ya impreso en el DOM

Compartir