Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

161
Views
React Link async/await does not wait code block

Hey I am trying to make small application for React-router I am trying to send API request (I do not have backend thats why im using promises) When i click Link it is redirecting not waiting my async/await could you tell me what am i doing wrong? First thought i can pass history with props and then

history.push("/someURL");

But my second thought is if i could do this with <Link I will pass less props (history).

To sum up i need to wait until my request(promise) over after that i need to change url

import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import { Link } from 'react-router-dom';
import { toast } from 'react-toastify';

const StyledButton = styled.button`
  width: 100%;
  border-radius: 10px;
  background-color: #24b571;
  color: #ffffff;
  font-weight: bold;
  margin-bottom: 5px;
`;

const SaveButton = ({
  children,
  saveValidation,
  message,
  to,
  setIsLoading,
}) => {
  const promiseFunc = () =>
    new Promise((resolve) => {
      setTimeout(() => {
        resolve(5);
      }, 5000);
    });

  const onClickHandler = async (event) => {
    setIsLoading(true);
    const control = saveValidation(); // returns true or false
    if (!control) {
      toast.error(message);
      event.preventDefault();
    } else {
      try {
        const a = await promiseFunc();
        alert(a);
      } catch {
        alert('error');
      }
      console.log(control);
    }
    setIsLoading(false);
  };

  return (
    <Link to={to}>
      <StyledButton onClick={onClickHandler}>{children}</StyledButton>
    </Link>
  );
};

export default SaveButton;

SaveButton.propTypes = {
  children: PropTypes.node.isRequired,
  saveValidation: PropTypes.func.isRequired,
  to: PropTypes.string.isRequired,
  message: PropTypes.string,
  setIsLoading: PropTypes.func,
};
SaveButton.defaultProps = {
  message: 'Fill all values',
  setIsLoading: () => {},
};
about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

Issue

The main issue here is that you are rendering TWO components/elements a user could interact with, which is generally considered anti-pattern in UI/UX. The button is clicked and its onClick handler is invoked, and the click event bubbles and the Link handles it by navigating. These events are handled separately from one another. You could stop the onClick event propagation in the button's click handler, but then the Link would stop working.

Solution

I suggest using the styled button alone and at the end of the asynchronous logic issue an imperative navigation instead of the declarative navigation offered by the Link. Use the useHistory hook from react-router-dom (or useNavigate if using RRDv6).

import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import { useHistory } from 'react-router-dom'; // <-- import hook
import { toast } from 'react-toastify';

const StyledButton = styled.button`
  ...
`;

const SaveButton = ({
  children,
  saveValidation,
  message,
  setIsLoading,
  to,
}) => {
  const history = useHistory(); // <-- use hook

  const promiseFunc = () => new Promise((resolve) => {
    ...
  });

  const onClickHandler = async (event) => {
    setIsLoading(true);
    const control = saveValidation();
    if (!control) {
      toast.error(message);
      event.preventDefault();
    } else {
      try {
        const a = await promiseFunc();
        alert(a);
      } catch {
        alert('error');
      }
      console.log(control);
    }
    setIsLoading(false);
    history.push(to); // <-- imperative navigation
  };

  return (
    <StyledButton onClick={onClickHandler}>{children}</StyledButton>
  );
};
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!