React: [bug] click not disabled on <fieldset disabled><button onClick={() => alert('clicked')}><span>click me</span></button></fieldset>

Created on 13 Sep 2016  路  11Comments  路  Source: facebook/react

bug

In the following

const Component = () =>
        <fieldset disabled>
            <button
              onClick={() => alert('clicked by React')}
            >click me here and <span style={{color: 'red'}}>here</span></button>
        </fieldset>;

clicking on click me here and will not trigger alert('clicked by React') whereas clicking on the red here will trigger alert('clicked by React').

Demo: https://jsfiddle.net/ropbvL3y/

Thanks for React, it's an incredibly well designed tool.

DOM Bug

Most helpful comment

Still reproducible, makes fieldset useless

All 11 comments

Thanks for the report @brillout, and for the great test case. I was able to reproduce using a build of the current master branch http://jsfiddle.net/jxx65yhy/

I'm fixing this issue

1.I fixed this issue, but Is this way is correct?
https://github.com/YutamaKotaro/react/commit/094124c8efa89e538578bb50c97ec4b93f5eab0d
if parent tag is form or fieldset having disabled, button will not fire in the case of clicking children span or div.
but even if parent div has disabled, children button will fire.

if click span, onClick will not fire

<fieldset disabled>
    <button onClick={() => alert('hello');}>
        click <span> here </span>
     </button>
</fieldset>

but in this case, if click span, onClick will fire

<div disabled>
    <button onClick={() => alert('hello');}>
        click <span> here </span>
     </button>
</div>

and more, if click span, onClick will fire

<fieldset disabled>
    <button>
        click <span onClick={() => alert('hello');}> here </span>
     </button>
</fieldset>

2.This issue didnt occuered in firefox.But Chrome, Safari has this issue.
This issue should leave it as specification of browser ?

3.I have question in the test.
This test give ReactComponent Object to traverseTwoPhase method. But in browser, traverseTwoPhase method receive Simple Object ( have tag, type ...), not receive ReactComponent Object.
How to write test case, should i do?

    it('should traverse two phase at shallowest node', () => {
      var parent = renderParentIntoDocument();
      var target = getInst(parent.refs.P);
      var expectedCalls = [['P', 'captured', ARG], ['P', 'bubbled', ARG]];
      ReactTreeTraversal.traverseTwoPhase(target, callback, ARG);
      expect(mockFn.mock.calls).toEqual(expectedCalls);
    });

Seems to be fixed in latest master.

@acdlite have there been changes merged to master since 16.0.0.rc-3 that would have resolved this? I'm seeing that the issue still occurs with the latest RC.

I'm seeing this in 16.2.0, can we reopen?

Still reproducible, makes fieldset useless

This is still present in 16.8.0

I suppose React should use something like element.matches(':disabled') before calling onClick so that it's really sure the button is disabled.

But this would probably be an expensive operation to perform on every button each time it's clicked.

Is the core team working on a solution or should the community send a PR?

For anyone looking for a quick workaround, you can change your onClick function to be:

<button
  onClick={evt => !evt.currentTarget.matches(':disabled') ? handleOnClick(evt) : undefined}
/>

Here's a codesandbox illustrating the bug. You can easily toggle between the React versions to troubleshoot. I have also confirmed that @FezVrasta's suggestion 鈽濓笍 does patch the bug for anyone looking for an interim solution.

image

  • Still present in 16.12.0
  • Chrome only

@brillout can you update the title of this issue so that it might get more exposure? I am thinking it has been ignored due to its cryptic title.

Was this page helpful?
0 / 5 - 0 ratings