Por que os documentos do React recomendam fazer AJAX em componentDidMount, não em componentWillMount?
102
O título diz tudo. Eu entendo por que componentDidMounté apropriado para qualquer coisa que requer acesso DOM, mas uma solicitação AJAX não necessariamente ou geralmente precisa disso.
@FurkanO Acho que ele quis dizer acesso a elementos DOM renderizados pelo componente. E ele está totalmente certo porque se você tentar acessar os referidos elementos componentWillMountnele falhará, visto que o componente ... não montou.
ZekeDroid
@AlanH. Excluí minha pergunta, é claro que você tem acesso ao dom no componentDidMount. Esta é uma regra, nada a explicar sobre isso. Obrigado.
FurkanO
Na minha opinião, o motivo pelo qual chamamos a função Ajax após componentDidMount é que primeiro temos que nos certificar de que o elemento está sendo renderizado sem problemas no início. Depois disso, podemos fazer uma chamada ajax. Se chamarmos ajax primeiro e algo de erro acontecer, isso causará um problema de renderização
Faris Rayhan
Respostas:
62
componentDidMounté para efeitos colaterais. Adicionar ouvintes de eventos, AJAX, alterar o DOM, etc.
componentWillMountraramente é útil; especialmente se você se preocupa com a renderização do lado do servidor (adicionar ouvintes de evento causa erros e vazamentos, e muitas outras coisas que podem dar errado).
Fala-se sobre a remoção componentWillMountde componentes de classe, uma vez que serve ao mesmo propósito que o construtor. Ele permanecerá nos createClasscomponentes.
Adicionar ouvintes de eventos causa erros e vazamentos o tempo todo no servidor ou apenas em componentWillMount? Eu realmente não vejo a diferença.
Alan H.
18
@Alan - Se você estiver usando o React tanto no lado do cliente quanto no lado do servidor, verá que tudo dentro dele componentWillMountserá executado em uma renderização do lado do servidor. Se você estivesse usando componentDidMount, isso só seria executado no lado do cliente. Como resultado, colocar coisas componentWillMountque executam interações externas ou vinculam-se a eventos, etc., não é uma boa ideia. Se você não tem planos de renderizar seus componentes no lado do servidor, ainda não é uma boa ideia apenas pela potencial portabilidade do código. Isso tudo está fora do motivo principal de ser ruim, o que é explicado na resposta de @daniula.
Mike Driver
3
componentWillMount é executado no servidor, mas componentWillUnmount (onde você remove ouvintes) não é. Isso faria com que você adicionasse ouvintes e nunca os limpasse.
Brigand
As pessoas da equipe principal do React estão considerando remover o componentWillMount de versões futuras.
cchamberlain
1
@AnkitSinghaniya interromperia a renderização do servidor e os testes de unidade rasos.
Brigand
36
Tive o mesmo problema no início também. Eu decidi tentar fazer pedidos, componentWillMountmas acabou em vários pequenos problemas.
Eu estava disparando a renderização quando a chamada ajax termina com novos dados. Em algum ponto, a renderização do componente demorou mais do que a obtenção da resposta do servidor e, nesse ponto, o retorno de chamada ajax estava disparando a renderização no componente não montado. Este é um tipo de caso extremo, mas provavelmente há mais, por isso é mais seguro seguir componentDidMount.
Ok, obrigado. Achei que pudesse ser algo assim, mas você está certo, é surpreendente que a solicitação de ajax pudesse terminar antes da renderização.
Alan H.
1
@daniula Tem certeza? Como a solicitação AJAX pode terminar antes de renderizar?
Leon Grapenthin de
4
Este é o mundo assíncrono do navegador. Você nunca deve presumir que uma função sempre será mais rápida que as demais. Como mencionei, é um caso extremo e provavelmente significa que você deve otimizar seu processo de renderização, mas usar o método de ciclo de vida adequado tornará sua vida muito mais fácil neste ponto.
daniula
1
@SooChengKoh ES6 construtor de classe é equivalente a componentWillMount, então você ainda deve continuar usando componentDidMountpara suas chamadas ajax.
daniula
1
@SooChengKoh - Definitivamente não deve fazer nada no construtor que levará ao estado que deve ser configurado, que levará a condições de corrida no cliente e no servidor. Você nunca deve chamar setStateum construtor de componente e não tem como determinar quando a chamada AJAX será concluída. twitter.com/dan_abramov/status/576453138598723585
cchamberlain
3
De acordo com a documentação, definir o estado em componentWillMountnão acionará uma nova renderização. Se a chamada AJAX não estiver bloqueando e você retornar um Promiseque atualiza o estado do componente em caso de sucesso, há chances de que a resposta chegue depois que o componente for renderizado. Como componentWillMountnão dispara uma re-renderização, você não terá o comportamento esperado, que é o componente sendo renderizado com os dados solicitados.
Se você usar qualquer uma das bibliotecas de fluxo e os dados solicitados acabarem no armazenamento ao qual o componente está conectado (ou herdar de um componente conectado), isso não será um problema, pois a recepção desses dados, provavelmente, mudará os props eventualmente.
componentWillMountnão dispara uma nova renderização apenas porque um novo estado é definido antes da primeira renderização. Mas se setStatefor chamado em um retorno de chamada AJAX, ele será definitivamente chamado após a primeira renderização e acionará uma nova renderização.
componentWillMount
nele falhará, visto que o componente ... não montou.Respostas:
componentDidMount
é para efeitos colaterais. Adicionar ouvintes de eventos, AJAX, alterar o DOM, etc.componentWillMount
raramente é útil; especialmente se você se preocupa com a renderização do lado do servidor (adicionar ouvintes de evento causa erros e vazamentos, e muitas outras coisas que podem dar errado).Fala-se sobre a remoção
componentWillMount
de componentes de classe, uma vez que serve ao mesmo propósito que o construtor. Ele permanecerá noscreateClass
componentes.fonte
componentWillMount
? Eu realmente não vejo a diferença.componentWillMount
será executado em uma renderização do lado do servidor. Se você estivesse usandocomponentDidMount
, isso só seria executado no lado do cliente. Como resultado, colocar coisascomponentWillMount
que executam interações externas ou vinculam-se a eventos, etc., não é uma boa ideia. Se você não tem planos de renderizar seus componentes no lado do servidor, ainda não é uma boa ideia apenas pela potencial portabilidade do código. Isso tudo está fora do motivo principal de ser ruim, o que é explicado na resposta de @daniula.Tive o mesmo problema no início também. Eu decidi tentar fazer pedidos,
componentWillMount
mas acabou em vários pequenos problemas.Eu estava disparando a renderização quando a chamada ajax termina com novos dados. Em algum ponto, a renderização do componente demorou mais do que a obtenção da resposta do servidor e, nesse ponto, o retorno de chamada ajax estava disparando a renderização no componente não montado. Este é um tipo de caso extremo, mas provavelmente há mais, por isso é mais seguro seguir
componentDidMount
.fonte
componentWillMount
, então você ainda deve continuar usandocomponentDidMount
para suas chamadas ajax.setState
um construtor de componente e não tem como determinar quando a chamada AJAX será concluída. twitter.com/dan_abramov/status/576453138598723585De acordo com a documentação, definir o estado em
componentWillMount
não acionará uma nova renderização. Se a chamada AJAX não estiver bloqueando e você retornar umPromise
que atualiza o estado do componente em caso de sucesso, há chances de que a resposta chegue depois que o componente for renderizado. ComocomponentWillMount
não dispara uma re-renderização, você não terá o comportamento esperado, que é o componente sendo renderizado com os dados solicitados.Se você usar qualquer uma das bibliotecas de fluxo e os dados solicitados acabarem no armazenamento ao qual o componente está conectado (ou herdar de um componente conectado), isso não será um problema, pois a recepção desses dados, provavelmente, mudará os props eventualmente.
fonte
componentWillMount
não dispara uma nova renderização apenas porque um novo estado é definido antes da primeira renderização. Mas sesetState
for chamado em um retorno de chamada AJAX, ele será definitivamente chamado após a primeira renderização e acionará uma nova renderização.