skip to Main Content

Is there a way to disable all the inputs, buttons, selects inside a react component on the basis of a state variable, or a prop of the component?

  • My react component has multiple such buttons, and inputs.
  • Some of them are rendered disabled on some boolean state variable, say bool1 as:
    <button disabled = {bool1}>Button 1</button>
    
  • Some buttons are rendered disabled on some boolean state variable, say bool2 as:
    <button disabled = {bool2}>Button 2</button>
    
  • Similarily, there are multiple elements that behave disabled on the basis of some state variable.

But what I want is, I have a state variable isCompDisabled, which when true, should disable all the inputs and buttons, etc. But, when it is false, the button or input should then revert back to its state as decided by the other boolean variable. This behaviour can be implemented by adding a conditional for every element. In short, the behaviour should be like:

<button disabled = {boolX || isCompDisabled}>Button X</button>

The problem in my use case is, that it would be lengthy process going to each input or button, and add a disabled logic on it. Is there a short way, or an entire other way of fulfilling my use case?

2

Answers


  1. Using Context:

    1. Create a context that will hold the global disabled state.
    import React, { createContext, useContext } from 'react';
    
    const DisabledContext = createContext();
    
    const useDisabledContext = () => useContext(DisabledContext);
    
    const DisableProvider = ({ isCompDisabled, children }) => {
      return (
        <DisabledContext.Provider value={isCompDisabled}>
          {children}
        </DisabledContext.Provider>
      );
    };
    
    1. Envelop your app or the portion of your component tree where you need this behavior with the DisableProvider.
    <DisableProvider isCompDisabled={isCompDisabled}>
      <YourComponent />
    </DisableProvider>
    
    1. Inside your component, you can create a custom hook to determine if the button should be disabled or not.
    const useDisabled = (localDisabled) => {
      const isCompDisabled = useDisabledContext();
      return localDisabled || isCompDisabled;
    };
    
    // Within your component
    const YourComponent = () => {
      const bool1 = someLogic();
      const isButton1Disabled = useDisabled(bool1);
      
      return <button disabled={isButton1Disabled}>Button 1</button>;
    };
    

    Using Higher-Order Component (HOC):

    1. Create a HOC that accepts a component and returns a new component with the disabling logic.
    const withDisable = (Component) => {
      return ({ isCompDisabled, disabled, ...props }) => {
        const finalDisabled = disabled || isCompDisabled;
        return <Component disabled={finalDisabled} {...props} />;
      };
    };
    
    1. Envelop your component with the HOC:
    const Button1 = withDisable(({ disabled }) => {
      return <button disabled={disabled}>Button 1</button>;
    });
    
    1. Utilize the wrapped component as usual:
    <Button1 isCompDisabled={isCompDisabled} disabled={bool1} />
    

    The HOC method directly envelops your components and injects the global disable prop. The context method may offer more flexibility by permitting you to utilize the disabling logic in any component, deep within your component tree without having to overtly pass the prop down through many layers.

    Login or Signup to reply.
  2. You can wrap all your inputs in a <fieldset> and use the disabled attribute there instead:

    <fieldset disabled={boolX || isCompDisabled}>
      // Your inputs and buttons...
    </fieldset>
    

    Note that form elements inside the <legend> element won’t be disabled.

    See the fieldset documentation.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search