Yige Song
Yige Song

Reputation: 373

React jsx Order of execution: <button> inside <a>

Imagine I have the below code:

<a href="URL">
    <button onCLick={this.doSomething}>do something</button>
<a>

If I click on the button, do I go to URL first or do I execute doSomething first?

In my experience, it goes to URL first. What if I want doSomething to execute first, then go to URL after doSomthing is done?

Appreciate your help ^_^!

Upvotes: 0

Views: 51

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370989

The handler will run first. This is why you can prevent the page from redirecting by calling preventDefault on the event - if the handler run after the page started redirecting, prevention of redirection wouldn't be possible:

const App = () => {
  const doSomething = (e) => {
    e.preventDefault();
    console.log('doing something');
  };
  return (
    <a href="https://example.com">
        <button onClick={doSomething}>do something</button>
    </a>
  );
};
ReactDOM.render(<App />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class="react"></div>

If you want to wait until doSomething is done, it sounds like it's asynchronous - call preventDefault on the event, like above, then assign to window.location.href when the function finishes.

const App = () => {
  const doSomething = (e) => {
    e.preventDefault();
    const { href } = e.target.parentElement
    console.log('doing something');
    setTimeout(() => {
      window.location.href = href;
    }, 2000);
  };
  return (
    <a href="https://example.com">
        <button onClick={doSomething}>do something</button>
    </a>
  );
};
ReactDOM.render(<App />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class="react"></div>

Upvotes: 2

Related Questions