Luke Schissler
Luke Schissler

Reputation: 31

State leaking between React sibling components

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 })
  }

Upvotes: 2

Views: 258

Answers (1)

Krzysztof Woliński
Krzysztof Woliński

Reputation: 406

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.

Upvotes: 2

Related Questions