skip to Main Content

I am trying to dynamically add pairs of buttons and text fields and have the button perform some action on its corresponding text field. My specific use case is creating a ‘User Settings’ page where users can change a specific account information property

Here is a minimal code example that generates 2 pairs of text fields and buttons. However, pressing either button disables both text fields rather than its corresponding text field:

export default function FAQ() {

    const [disabled, toggleDisabled] = React.useState(false)

    const CreateInputPair = () => {
        return (
            <>
                <TextField
                    disabled={disabled}
                />
                <Button
                    onClick={() => toggleDisabled(!disabled)}
                >
                    Toggle Disabled
                </Button>
            </>
        )
    }

    return (
        <>
            <CreateInputPair />
            <br />
            <CreateInputPair />
        </>
    );

}

In the above example, how can I make it so that pressing a button only disables its associated text field?

My current and naive approach for reading values of dynamically created elements is to assign id prop fields to the TextField and manipulate the DOM to read the value (ie. having document.getElementById(e.target.id).value inside a onClick={(e) => handleChange(e)} method), but this goes against the principles of React

2

Answers


  1. Move CreateInputPair into its own separate component.

    const InputPair = () => {
        const [disabled, toggleDisabled] = React.useState(false);
        return (
            <>
                <TextField
                    disabled={disabled}
                />
                <Button
                    onClick={() => toggleDisabled(!disabled)}
                >
                    Toggle Disabled
                </Button>
            </>
        )
    }
    export default function FAQ() {
        return <>
            <InputPair /> <br /> <InputPair />
        </>;
    }
    
    Login or Signup to reply.
  2. I hope this helps

    import { useState } from "react";
    
    export default function FAQ() {
      const [disabled, toggleDisabled] = useState();
    
      const toggleDisabledInput = (id) => {
        if (disabled === id) {
          toggleDisabled(null);
        } else {
          toggleDisabled(id);
        }
      };
    
      console.log(disabled);
    
      const CreateInputPair = ({ id }) => {
        return (
          <>
            <input disabled={disabled === id} />
            <button onClick={() => toggleDisabledInput(id)}>Toggle Disabled</button>
          </>
        );
      };
    
      return (
        <>
          <CreateInputPair id="1" /> // you can pass id from your db
          <br />
          <CreateInputPair id="2" />
        </>
     );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search