5

I have button which by default was disabled. But when the checkbox was selected, button will be enabled, using ref i am enabling the button. After the button activated click event is not firing. Without the default disable, button's click event was firing.

    class TodoApp extends React.Component {

        onChangeCheckBox(event) {
            if(event.target.checked) {
                this.actionButtonRef.disabled = "";
            }
            else {
                this.actionButtonRef.disabled = "disabled";

            }
        }  

        render() {
            return (
            <div>
                <input 
                    type="checkbox" 
                    ref={element => {
                        this.checkboxAllRef = element;
                    }}
                    onChange={event => this.onChangeCheckBox(event)}/> Checbox 
                <br />
                <button
                    type="button"
                    className="btn btn-danger" 
                    ref={element => {
                        this.actionButtonRef = element;
                    }}
                    onClick={event => {
                        alert("clicked");
                    }} 
                    disabled="disabled">Button</button>
            </div>
            )
        }
    }

    ReactDOM.render(<TodoApp />, document.querySelector("#app"))

here is jsfiddle

1
  • Yes i know that we can do with state above code. But i actually want to know why is not working. So i got the answer here github.com/facebook/react/issues/12704 Commented May 2, 2018 at 8:08

3 Answers 3

2

Manual mutation of DOM elements (actually say virtual DOM) is not allowed by React.

You need to keep the enabled or disabled state. And work based on the state changes:

Class Constructor:

  constructor(props) {
    super(props);

    this.state = {
      checked: false
    };

    this.onChangeCheckBox = this.onChangeCheckBox.bind(this);
    this.onClickButton = this.onClickButton.bind(this);
  }

Event Handlers:

  onChangeCheckBox(e) {
    this.setState({
      checked: e.target.checked,
    });
  }
  onClickButton(e) {
    alert(e);
  }

Render JSX:

  render() {
    return (
      <div>
        <input
          type="checkbox"
          checked={this.state.checked}
          onChange={this.onChangeCheckBox}
        />
        <button
          type="button"
          disabled={!this.state.checked}
          onClick={this.onClickButton}>Click</button>
      </div>
    );
  }
}

Here is a demo.

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for the answer. I know that we can done this by using the state. But the problem is, i don't want to re-render the component when the button was disabled/enabled. Is this is the only way to achieve it? And also i what to know the reason why i click event is not triggering. Because i can't find the any reason for it
See the sentence that is on bold. So, if you want not to re-render then you can use shouldComponentUpdate hook while using / updating the state.
but when i am changing the textbox value using the ref it was changed without component re-render. Also button was enabled using the ref, but the click event is not triggering. That makes me confused
That's the issue. React will not allow you to work with manual mutation of dom.
So that i can consider like this. Using the ref we can change the properties but events will not update without re-render
|
2

Try this JSfiddle link

class TodoApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {      //Set initial state here
      btnDisabled: true
    };
  }
  onChangeCheckBox(event) {
    if (event.target.checked) {
      this.setState({ btnDisabled: false }); //Set new state here
    } else {
      this.setState({ btnDisabled: true });  //Set new state here
    }
  }
  render() {
    return (
      <div>
        <input
          type="checkbox"
          onChange={event => this.onChangeCheckBox(event)}
        />{" "}
        Checbox
        <div>
          <button
            type="button"
            className="btn btn-danger"
            onClick={event => {
              alert("clicked");
            }}
            disabled={this.state.btnDisabled}  //Always use state 
          >
            Button
          </button>
        </div>
      </div>
    );
  }
}

ReactDOM.render(<TodoApp />, document.querySelector("#app"));

Your component was not getting rerendered, because u didn't call setstate on click of checkbox.On click of checkbox, u need to call setState and set the btnDisabled to false.

When setState occurs, reactjs rerenders the component. In doing so, it will make the button enabled.

You should not over use refs in React.

Refs should be used sparingly Also refer this answer for best practices for disabling button how-to-disable-button-in-react-js

8 Comments

Thanks for the answer. I know that we can done this by using the state. But the problem is, i don't want to re-render the component when the button was disabled/enabled. Is this is the only way to achieve it? And also i what to know the reason why i click event is not triggering. Because i can't find the any reason for it
@Sivabalan in your question, u were using refs to change the button's disabled attribute, U changed it, by updating the DOM, but react didnt know about it.
when u clicked on it, react still thought the button is disabled
By using setstate, u told react to update the DOM. Before that u were updating it urself.
but when i am changing the textbox value using the ref it was changed without component re-render. Also button was enabled using the ref, but the click event is not triggering. That makes me confused
|
0

You should try using the values true or false as values for the disabled property on the button instead of disabled and ""

The button won't properly toggle between disabled and not if these aren't set correctly and therefore you won't be able to do the click event.

On a side note it's usually considered best practice to use refs as little as possible, you could achieve a similar, more desired outcome by using state to toggle between true and false

1 Comment

Thanks for the answer. But it didn't work even changing the values to true and false

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.