Quentin M.
Quentin M.

Reputation: 47

Update props of specific component

I've got an array full of rooms:

const room = (<Room
    points={points}
    scene={this.scene}
    key={this.rooms.length}
    keyV={this.rooms.length}
    />)

this.rooms.push(room);

Now for example I got 3 rooms each with their own initial points:
Room 1 : points={a,b,c}
Room 2 : points={d,e,f}
Room 3 : points={g,h,i}

Now I want to update the points of room 2 to {d,e,f,x} (this.points). I know this can be done with:

this.setState({points: this.points})

But this updates the points of all the rooms. I want to only update room 2 with new points. How can this be achieved?

Update:
I create a room when I draw two lines. Now when I draw the third line the existing room needs to be updated with an extra point.

Upvotes: 1

Views: 65

Answers (1)

Dev
Dev

Reputation: 3932

When you setState, make sure you update the actual rooms. For instance, when you are creating Room component, you can have some index or some identifier to identity which Room you want to update.

<Room points={...} onUpdate={()=>{this.onUpdate(someId)}} 

Your onUpdate fn could be like

onUpdate(RoomIdToUpdate) {
  let updatedRooms = this.rooms.map((room) => {
    if(room.id === RoomIdToUpdate) {
      return Object.assign({}, room, {
        points: [...yourUpdatedPointsArray]
      })
    }
    return room;
  })
}

Then you can set state

this.setState({
  rooms: updatedRooms
})

Hope this helps.

Update:

Have a look at the below sample for reference. Check the componentWillReceiveProps() fn and my comments for better understanding

// componentWillReceiveProps will be called as Room component will receive new props.
class Room extends React.Component {
  componentWillReceiveProps(nextProps) {
    console.log(nextProps) //new props
    console.log(this.props) //old props
  }
  
  render() {
    return(
      <div>
         {this.props.data.roomNo}
         <button onClick={this.props.updateRoom}> Update Room</button>
      </div>
    )
  }
  
}

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { 
      roomsData: [
        {
          points: [1,2],
          roomNo: 1
        },
        {
          points: [3,4],
          roomNo: 2
        },
        {
          points: [5,6],
          roomNo: 3
        }
      ]
    };
    this.updateRoom = this.updateRoom.bind(this);
  }
  
  updateRoom(roomNoToUpdate) {
    let newPoints = [2,3,4,5];
    let updatedRoomsData =  this.state.roomsData.map((data) => {
      if(data.roomNo === roomNoToUpdate) {
        return Object.assign({}, data, {
          points: [...newPoints]
        })
      } else {
        return data
      }
    })

    this.setState({ roomsData: updatedRoomsData });
  }


  render() {
    return (
      <div>
        {
          this.state.roomsData.map((data, index) => {
            return <Room key={index} data={data} 
                    updateRoom={() => this.updateRoom(data.roomNo)}
                  />
          })
        }
        
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Upvotes: 1

Related Questions