3

In ReactJS, I want to enable/disable a button dynamically. For that, I created a function to check the form field from state. But it's not working.

I tried the below code

render() {


    const canSave = true;  // Working

    // Not working
    const canSave = () => {
        const { paramCode, paramDesc, paramValue } = this.state.row;
        if (this.state.row && paramCode && paramDesc && paramValue) {
            return true;
        }
        return false
    }



    /* For Create Dialog  */
    let createDialogFooter = <div className="ui-dialog-buttonpane p-clearfix">
        <Button label="Save"  disabled={canSave} />
    </div>;

Console Error:-

    index.js:1375 Warning: Invalid value for prop `disabled` on <button> tag. Either remove it from the element, or pass a string or number value to keep it in the DOM. For details, see https : // fb.me/react-attribute-behavior
        in button (created by Button)
        in Button (at SearchPriceParameters.jsx:210)
        in div (at SearchPriceParameters.jsx:209)
        in div (created by Dialog)
        in div (created by Dialog)
        in Transition (created by CSSTransition)
        in CSSTransition (created by Dialog)
        in Dialog (at SearchPriceParameters.jsx:249)
        in div (at SearchPriceParameters.jsx:233)
        in SearchPriceParameters (created by Context.Consumer)
        in Route (at App.js:34)
        in Switch (at App.js:29)
        in div (created by Container)
        in Container (at App.js:28)
        in div (at App.js:27)
        in div (at App.js:16)
        in App (at src/index.js:15)
        in Router (created by BrowserRouter)
        in BrowserRouter (at src/index.js:14)

Update:-

Thanks for the answers, now the below-fixed code works.

render() {
    /** Enable / disable button */
    const canSave = () => {
        if (this.state.row) {
            const { paramCode, paramDesc, paramValue } = this.state.row;
            return (paramCode && paramDesc && paramValue);
        }
        return false;
    }


    /* For Create Dialog  */
    let createDialogFooter = <div className="ui-dialog-buttonpane p-clearfix">
        <Button label="Save" icon="pi pi-check" onClick={this.save} className="p-button-warning" disabled={!canSave()} />
    </div>;

3 Answers 3

6

Two problems here.

You're never returning false. Try like this.

const canSave = () => {
     const { paramCode, paramDesc, paramValue } = this.state.row;
     return (this.state.row && paramCode && paramDesc && paramValue)
}

You're never executing canSave

<Button label="Save"  disabled={canSave()} />
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks it works now. I didn't use the brackets earlier for canSave()
1

what is the trigger to enable/disable button dynamically?

Are you changing the values in the state? if so append a flag with the existing state which indicate the disable/enable value of the button.

Comments

1

It's better you move the function out of render method.

Also I think you don't need to check this.state.row again for falsy values.

import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";

class App extends React.Component {
  state = {
    row: { paramCode: "hello" }
  };
  canSave = () => {
    const { paramCode } = this.state.row;
    return paramCode;
  };
  render() {
    let showButton = <button disabled={this.canSave()}>Click me</button>;
    return <div className="App">{showButton}</div>;
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Hope that helps!!!

3 Comments

Many thanks, I get confused when to use inside and out. I tried out and it gives this error. index.js:1375 Warning: Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render. Or maybe you meant to call this function rather than return it.
Thanks moving outside also works. And I accessed it using this keyword inside button... disabled={!this.canSave()}. Finally which approach is the best practice. keeping the code outside render?
functions should be outside render for many reasons but sometimes it's just personal preference - see this link in favour of functions outside render.

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.