1
resposta

[Dúvida] React Router v6 e pagamentos

Depois do select com as formas de pagamento, o meu botão de voltar não funciona como deveria. Clico em voltar e não volta, mas quando faço a troca dos pagamentos ou tento adicionar mais um produto direto no carrinho, sou redirecionado para a feira. No console recebo esse alerta em carrinho: You should call navigate() in a React.useEffect(), not when your component is first rendered. Porém não consegui pensar em uma forma de resolver esse problema com useEffect na aplicação.

E quando sou redirecionado para a feira, recebo esse: ** Cannot update a component (RouterProvider) while rendering a different component (Carrinho). To locate the bad setState() call inside Carrinho**

Carrinho

function Carrinho() {
  const [openSnackbar, setOpenSnackbar] = useState(false);
  const {carrinho} = useCarrinhoContext();
  const {saldo} = useContext(UsuarioContext)
  const {formaPagamento, tiposPagamento, mudarFormaPagamento} = usePagamentoContext();;
  const navigate = useNavigate();

  return (
    <Container>
      <Voltar onClick={navigate('/feira')}/>
      <h2>
        Carrinho
      </h2>
      {carrinho.map(produto => (
        <Produto {...produto} key={produto.id}/>
      ))}
      <PagamentoContainer>
        <InputLabel> Forma de Pagamento </InputLabel>
        <Select onChange={(e) => mudarFormaPagamento(e.target.value)} value={formaPagamento.id}>
          {tiposPagamento.map(pagamento => (<MenuItem key={pagamento.id} value={pagamento.id}>{pagamento.nome}</MenuItem>))}
        </Select>
      </PagamentoContainer>
      <TotalContainer>
          <div>
            <h2>Total no Carrinho: </h2>
            <span>R$ {carrinho.reduce((cont, item) => cont + (item.valor * item.quantidade), 0)}</span>
          </div>
          <div>
            <h2> Saldo: </h2>
            <span> R$ {saldo}</span>
          </div>
          <div>
            <h2> Saldo Total: </h2>
            <span> R$ </span>
          </div>
        </TotalContainer>
      <Button
        onClick={() => {
          setOpenSnackbar(true);
        }}
        color="primary"
        variant="contained"
      >
         Comprar
       </Button>
        <Snackbar
          anchorOrigin={
            { 
              vertical: 'top',
              horizontal: 'right'
            }
          }
          open={openSnackbar}
          onClose={() => setOpenSnackbar(false)}
        >
           <MuiAlert
            onClose={() => setOpenSnackbar(false)}
            severity="success"
          >
            Compra feita com sucesso!
          </MuiAlert>
        </Snackbar>
    </Container>
  )
}

routes.js

const Router = () => {
  const router = createBrowserRouter([
    {
      path: "/",
      element: <Login />,
    },
    {
      path: "/feira",
      element: <Feira />,
    },
    {
      path: "/carrinho",
      element: <Carrinho />,
    },
  ]);
  return (
    <UsuarioProvider>
      <CarrinhoProvider>
        <PagamentoProvider>
          <RouterProvider router={router} />
        </PagamentoProvider>
      </CarrinhoProvider>
    </UsuarioProvider>
  );
};
1 resposta

Olá Mauricio! Tudo ok contigo?

Vamos tentar resolver esses problemas!

Primeiro, em relação ao botão de voltar que não está funcionando corretamente, o problema pode estar no evento onClick que você está passando para o botão. Ao invés de utilizar onClick={navigate('/feira')}, você precisa passar uma função que chama o navigate() dentro dela. Por exemplo:

<Voltar onClick={() => navigate('/feira')} />

Dessa forma, o navigate() só será chamado quando o botão for clicado.

Agora, em relação ao alerta no console que diz para você chamar o navigate() dentro de um useEffect(), você pode tentar fazer o seguinte:

useEffect(() => {
  navigate('/feira');
}, []);

Isso significa que o navigate() será chamado apenas uma vez, quando o componente for renderizado pela primeira vez. Certifique-se de importar o useEffect corretamente do React.

Por fim, em relação ao erro relacionado ao setState(), parece que você está tentando atualizar o estado de um componente (RouterProvider) enquanto outro componente (Carrinho) está sendo renderizado. Isso pode ser um problema de sincronização entre os componentes. Uma solução possível é utilizar o setState() dentro do useEffect(), assim como sugerido no alerta do console. Por exemplo:

useEffect(() => {
  // Atualize o estado aqui utilizando setState()
}, []);

Lembre-se de importar o useEffect corretamente do React.

Espero que essas sugestões possam te ajudar a resolver os problemas que você está enfrentando. Se ainda tiver alguma dúvida, fique à vontade para perguntar!

Espero ter ajudado, abraços e bons estudos!

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software