3
respostas

Método render sendo chamado duas vezes

Estou tentando fazer algumas implementações na TimeLine porém, percebi que o metodo render() está sendo chamado duas vezes. Existe alguma forma de impedir o componente de renderizar duas vezes?

import React, { Component } from 'react';
import FotoItem from './FotoItem';
import ReactCSSTransitionGroup  from 'react-addons-css-transition-group';
import TimelineApi from '../logicas/TimelineApi';
import {connect} from 'react-redux';

class TimeLine extends Component {
    constructor(props){
        super(props);
        this.login = this.props.login;
    }

    carregarFotos(){
        let urlPerfil;

        if(this.login === undefined)
            urlPerfil = `https://instalura-api.herokuapp.com/api/fotos?X-AUTH-TOKEN=${localStorage.getItem('auth-token')}`;
        else
            urlPerfil = `https://instalura-api.herokuapp.com/api/public/fotos/${this.login}`;

        this.props.lista(urlPerfil);
    }

    componentDidMount(){
        this.carregarFotos();
    }

    componentWillReceiveProps(nextProps){
        if(nextProps.login !== this.login){
            this.login = nextProps.login;
            this.carregarFotos();
        }
    }

    render(){
        return (
        <div className="fotos container">
        <ReactCSSTransitionGroup
            transitionName="timeline"
            transitionEnterTimeout={500}
            transitionLeaveTimeout={300}>
            {
            this.props.fotos.map(foto => <FotoItem key={foto.id} foto={foto} like={this.props.like} comenta={this.props.comenta}/>)
            }        
        </ReactCSSTransitionGroup>
        </div>            
        );
    }
}

const mapStateToProps  = state => {
    console.log("Chamou");
    return {fotos: state.timeline}
}

const mapDispatchToProps = dispatch =>{
    return {
        like: (fotoId) =>{
            dispatch(TimelineApi.like(fotoId))
        },
        comenta: (fotoId, Comentario) =>{
           dispatch(TimelineApi.comenta(fotoId, Comentario));
        },
        lista: (urlPerfil) =>{
            dispatch(TimelineApi.lista(urlPerfil));
        }
    }
}

const TimelineContainer = connect(mapStateToProps, mapDispatchToProps)(TimeLine);

export default TimelineContainer;
3 respostas

Fala aí Ednir, tudo bem? Isso vai acontecer por causa do fluxo do React e Redux.

O primeiro render será feito da forma normal do componente, depois, o segundo render é feito após disparar as ações e atualizar a store do seu reducer.

Tem como melhorar sim, mas, são assuntos um pouco mais avançados e complexos (além de serem features novas).

Espero ter ajudado.

Obrigado pela resposta Matheus!

Como forma de melhoria coloquei uma verificação pra ver se meus Status está vazio, se estiver ele renderiza um loading e depois quando estiver preenchido ele irá renderizar a página completa.

Boa, geralmente é assim que fazemos mesmo, enquanto não carrega mostra um Loading, Spinner (ou qualquer outro nome) e após carregar mostra os dados.

Você pode fazer isso com um HOC (Hight Order Component), mas, um if também resolve, depois dê uma olhada nos HOC's.

Depois dá uma olhada nesse post:

http://blog.matheuscastiglioni.com.br/code-splitting-e-lazy-loading-no-react

Tem alguns recursos novos no React para esse tipo de implementação com o Suspense e fallback.

Espero ter ajudado.