0

So, I have a few components passing down a function to update the main component's state and then I want to re-render on the grandchild's component...

class GrandParentComponent extends Component {
  state = {
    formData: {
      rooms: [],
    },
  }

// has a function: handleRoom
handleRoom = room => {
  let roomsArray = this.state.formData.rooms.slice();
  let newRooms = [...roomsArray, room]; // add room to array
  this.setState({
    formData: update(this.state.formData, { rooms: { $set: newRooms }}),
  }); // update and $set comes from 'immutability-helper'
}
</GrandParentComponent>

Passes down to ParentComponent
<ParentComponent handleRoom={this.handleRoom} formData={this.state.formData} />

Passes down to ChildComponent
<ChildComponent handleRoom={this.props.handleRoom}  />

In thie child component, I want to update the state of the grandparent component.

handleSaveRoom = room => { this.props.handleRoom(room); }
// great this successfully updates the grandparent...

After the grandparent component is updated, I want to re-render the ParentComponent using the new data:

<ParentComponent handleRoom={this.handleRoom} formData={this.state.formData} >

handleCreateAddRoomForm = (room, i = 0) => {
  return (
    <Panel header={room.title} key={i}>
      <AddRoomForm room={room} />
    </Panel>
   )
}

render() {
  const { formData } = this.props;
  const renderRooms = formData.rooms.length 
    ? formData.rooms.map((room, i) => {
      this.handleCreateAddRoomForm(room, i);
    })
    : this.handleCreateAddRoomForm({title: 'New Room'});

  return (
    <div>
      {renderRooms}
    </div>
  )
 }
</ParentComponent>

So, I get back the room found... not sure about the (13 Not Found)... but the <Panel /> does not show in the <ParentComponent />

Ideally, when the data is updated on the <Grandparent /> from the <Child /> the <Parent /> should create a <Panel /> component to show the change...

Thoughts?

2
  • I don't see where you hand down the state data? Commented Mar 16, 2018 at 19:09
  • @ChristianM Okay, I have added formData to show how it is passed Commented Mar 16, 2018 at 19:22

1 Answer 1

1

Your map function must be returning undefined. Your formData.rooms.map returns nothing.

const renderRooms = formData.rooms.length 
  ? formData.rooms.map((room, i) => {
    this.handleCreateAddRoomForm(room, i);
  })
  : this.handleCreateAddRoomForm({title: 'New Room'});

try it like this instead (notice how I removed the { } in the map). If you want to keep the { } make sure you return the value.

const renderRooms = formData.rooms.length 
  ? formData.rooms.map((room, i) => this.handleCreateAddRoomForm(room, i))
  : this.handleCreateAddRoomForm({title: 'New Room'});

or

const renderRooms = formData.rooms.length 
  ? formData.rooms.map((room, i) => {
    return this.handleCreateAddRoomForm(room, i);
  })
  : this.handleCreateAddRoomForm({title: 'New Room'});
Sign up to request clarification or add additional context in comments.

3 Comments

Yeah without the return it thinks you return undefined
So, I want to dynamically create another <Panel> component, which would mean I need to add a new object into the formData.rooms array?
Exactly. As long as you pass down that array to your child component, it should update it automatically

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.