0

I'm fairly new to React. I have built a component that adds an input field onClick. What I need to do is add functionality to a button underneath each new input that deletes that specific input. For example, if 3 inputs are created 1,2,3 and input 2 is deleted 1 and 3 remain.

My code contains a function named onRemoveChild() that has some commented out code of my initial attempt at solving the problem using closest(). The issue with this is that state isn't correctly updated so after an input is removed the field label numbers are out of sync.

Thanks in advance and let me know if more explanation is needed.

import React from 'react'
import { 
    Button,
    TextField,
    Typography, 
    } from '@material-ui/core'

class TextFieldAddNew extends React.Component {
    state = {
      numChildren: 0
    }

    render () {
      const children = [];
      for (var i = 0; i < this.state.numChildren; i += 1) {
        children.push(<ChildComponent key={i} number={i+2} removeChild={this.onRemoveChild} />);
      };
      return (
        <ParentComponent addChild={this.onAddChild} theCount={this.state.numChildren}>
          {children}
        </ParentComponent>
      );
    }

    onAddChild = () => {
      this.setState({
        numChildren: this.state.numChildren + 1
      });
    }
    onRemoveChild = () => {
      document.getElementById('removeInput').closest('div').remove();
    }
  }

  const ParentComponent = (props) => (
    <div className="card calculator">
      <div id="childInputs">
        {props.children}
      </div>
      {
        props.theCount >= 4 ? (
          <div className="warning">
            We recommend adding no more that 5 opt-in's
          </div>
        ) : ''
      }
      <Button
        className="addInput"
        onClick={props.addChild}>
            + Add another option
      </Button>
    </div>
  );

  const ChildComponent = (props) => (
    <>
      <TextField 
          id={'opt-in-' + props.number}
          label={'Opt-in ' + props.number}
          name={'opt-in'}
          variant="outlined" 
          size="small" 
          margin="normal" 
          color="secondary"
          className="halfInput"
      />
      <Typography id="removeInput" className="removeInput"
        onClick={props.removeChild}>
          - Remove option
      </Typography>
      </>
  );

export default TextFieldAddNew;
1
  • How are you keeping track of the indexes and the values of the inputs? You could also use that to keep track of what's displayed or destroyed. Commented Feb 20, 2020 at 22:38

1 Answer 1

2

You can pass the index as part of calling removeChild like below:

children.push(<ChildComponent key={i} number={i+2} removeChild={()=>{this.onRemoveChild(i)}}

Also instead of keeping the numChildren in the state, you should keep the children. This way it would be easy to remove and add nodes to it. Then you can easily do: children.splice(i,1) and then update the state, this way auto render will update the dom for you.

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

Comments

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.