2

I'm having an issue with React passing state between sibling components when one of the siblings is deleted.

In my program, each component Plant has a state "watered", which has a default of "", and can be updated to the current day by pressing a button. When I delete a plant that has a non-empty watered state, that state passes to the next plant component.

I am sure that the correct item is being deleted by directly monitoring the keys in the parent.

Does this have something to do with a memory leak? Is there some code I can add to componentWillUnmount() method to solve this?

Thanks!

Edit: My Plant class

class Plant extends React.Component {
state = {
    watered : "",
    note: "",
    animate : "",
    modalState: false
};

noteRef = React.createRef()

water = e => {
    this.toggleAnimation()
    const date = new Date();
    const formatDate = date.getMonth().toString().concat('/', date.getDate())

    this.setState({watered : formatDate})
}

toggleAnimation = () => {
    this.setState({animate : "shake"});
    setTimeout(() => {
        this.setState({animate : ""})
    }, 500);
}

componentDidMount() {
    this.toggleAnimation()
}

componentWillUnmount() {
}

addNote = () => {
    this.setState({modalState : true})
}

hideModal = () => {
    const msg = "Variety : ".concat(this.noteRef.current.value)

    this.setState({note:msg})
    this.setState({modalState : false })
}

render() {
    return (

    <div>
        <Modal show={this.state.modalState}>
            <Modal.Header>Enter a variety for your plant!</Modal.Header>
            <Modal.Body>
                <input type="text" ref={this.noteRef} placeholder="Variety"/>
            </Modal.Body>
            <Modal.Footer>
                <button onClick={this.hideModal}>Save</button>
            </Modal.Footer>
        </Modal>
    <Card className={"plant-card".concat(this.state.animate)} >
        <Card.Body className="card-body">
            <Card.Title className="plant-card-title">
                <span className="plant-card-title">{this.props.name}</span>
            </Card.Title>
        </Card.Body>
        <Card.Text>
            {this.state.note}
            {this.state.watered}
            <Container className="icon-div">
                <img src={"images/watering-can.png"}
                     className="small-icon"
                     alt="can"
                     onClick={this.water}/>
                <img src={"images/shovel.png"}
                     className="icon"
                     alt="shovel"
                     onClick={() => this.props.removeFromGarden(this.props.index)}/>
                <img src={"images/grain-bag.png"}
                     className="icon"
                     alt="bag"
                     onClick={() => this.props.addHarvests(this.props.name, 1)}/>
                <img src={"images/wheelbarrow.png"}
                     className="small-icon"
                     alt="bag"
                     onClick={this.addNote}/>
            </Container>
        </Card.Text>
    </Card>

    </div>
) }

export default Plant;`

Removing a plant from state in my App component (main parent)

  removeFromGarden = key => {
  const garden = {...this.state.garden };
  delete garden[key]
  this.setState({garden })
  }

1 Answers1

2

This might occur if you're using an index as a key of the components in the array. Make sure that after deleting an element, all remaining elements preserve their original keys - if not, react will interpret the next element as the deleted one.

Krzysztof Woliński
  • 328
  • 1
  • 2
  • 12
  • I manually checked my "garden" state that holds all my plants. When I delete a plant from the garden, only the intended plant is removed, and the remainders maintain their key. The next plant in the state "inherits" the deleted plant's state however. – Luke Schissler Aug 13 '20 at 16:40