Quero que meu aplicativo ReactJS notifique um usuário ao navegar para fora de uma página específica. Especificamente, uma mensagem pop-up que o lembra de fazer uma ação:
"As alterações foram salvas, mas ainda não foram publicadas. Quer fazer isso agora?"
Devo acionar isso react-router
globalmente ou isso é algo que pode ser feito na página / componente de reação?
Não encontrei nada sobre o último e prefiro evitar o primeiro. A menos que seja a norma, é claro, mas isso me faz pensar em como fazer isso sem ter que adicionar código a todas as outras páginas possíveis que o usuário pode acessar.
Quaisquer insights são bem-vindos, obrigado!
reactjs
react-router
Barry Staes
fonte
fonte
componentWillUnmount() { if (confirm('Changes are saved, but not published yet. Do that now?')) { // publish and go away from a specific page } else { // do nothing and go away from a specific page } }
para que você possa chamar sua função de publicação antes de sair da páginaRespostas:
react-router
v4 apresenta uma nova maneira de bloquear a navegação usandoPrompt
. Basta adicionar ao componente que você deseja bloquear:Isso bloqueará qualquer roteamento, mas não a atualização ou o fechamento da página. Para bloquear isso, você precisará adicionar isto (atualizando conforme necessário com o ciclo de vida React apropriado):
onbeforeunload tem vários tipos de suporte por navegadores.
fonte
onberforeunload
alerta.react-router
não oferece suporte para isso fora da caixa (assumindo que o botão Cancelar não acione nenhuma alteração de rota). Você pode criar seu próprio modal para simular o comportamento.onbeforeunload
, você vai querer limpá-lo quando o componente for desmontado.componentWillUnmount() { window.onbeforeunload = null; }
No react-router
v2.4.0
ou superior e antes,v4
existem várias opçõesonLeave
paraRoute
setRouteLeaveHook
paracomponentDidMount
Você pode impedir que uma transição aconteça ou avisar o usuário antes de sair de uma rota com um gancho de saída.
Observe que este exemplo faz uso do
withRouter
componente de ordem superior introduzido emv2.4.0.
No entanto, essa solução não funciona perfeitamente ao alterar a rota no URL manualmente
No sentido de que
Para
react-router v4
usar Prompt ou histórico personalizado:No entanto
react-router v4
, é bastante mais fácil de implementar com a ajuda dePrompt
from'react-routerDe acordo com a documentação
Em seu método de renderização, você simplesmente precisa adicionar isso conforme mencionado na documentação de acordo com sua necessidade.
ATUALIZAR:
No caso de desejar ter uma ação personalizada a ser executada quando o uso estiver saindo da página, você pode usar o histórico personalizado e configurar seu roteador como
history.js
e, em seguida, na sua componente que você pode fazer uso de
history.block
comofonte
<Prompt>
o URL é alterado quando você pressiona Cancelar no prompt. Problema relacionado: github.com/ReactTraining/react-router/issues/5405Para
react-router
2.4.0+NOTA : É aconselhável migrar todo o seu código para o mais recente
react-router
para obter todas as novidades.Conforme recomendado na documentação do roteador react :
Deve-se usar o
withRouter
componente de ordem superior:Como um exemplo ES6 da documentação:
fonte
Para
react-router
v3.xEu tive o mesmo problema em que precisava de uma mensagem de confirmação para qualquer alteração não salva na página. No meu caso, eu estava usando o React Router v3 , então não pude usar
<Prompt />
, que foi apresentado a partir do React Router v4 .Eu lidei com 'clique no botão voltar' e 'clique acidental no link' com a combinação de
setRouteLeaveHook
ehistory.pushState()
, e lidei com 'botão recarregar' com oonbeforeunload
manipulador de eventos.setRouteLeaveHook ( doc ) & history.pushState ( doc )
Usar apenas setRouteLeaveHook não era suficiente. Por algum motivo, o URL foi alterado, embora a página permanecesse a mesma quando o 'botão Voltar' foi clicado.
onbeforeunload ( doc )
É usado para lidar com o botão de 'recarga acidental'
Abaixo está o componente completo que escrevi
this.props.router
.this.props.route
é transmitido do componente de chamadanote que
currentState
é passado como prop para ter estado inicial e para verificar qualquer mudançaPor favor, deixe-me saber se houver alguma dúvida :)
fonte
Para
react-router
v0.13.x comreact
v0.13.x:isso é possível com os métodos estáticos
willTransitionTo()
ewillTransitionFrom()
. Para versões mais recentes, veja minha outra resposta abaixo.Da documentação do react-router :
Para
react-router
1.0.0-rc1 comreact
v0.14.x ou posterior:isso deve ser possível com o
routerWillLeave
gancho do ciclo de vida. Para versões mais antigas, veja minha resposta acima.Da documentação do react-router :
Coisas. pode mudar antes do lançamento final.
fonte
Você pode usar este prompt.
fonte
Usando history.listen
Por exemplo, como abaixo:
Em seu componente,
fonte