How to add object array into nested property with nested map key?

时间:2019-04-16 22:35:39

标签: reactjs mapping semantic-ui-react

I'm trying to insert an object into a nested property with an onClick handler method using the key of a mapped state object and render a new table row with blank property fields. I DON'T want to change any nested property fields, I just want to add a brand new object to the nested property.

Initial state:

this.state = {
 sites: [{
  id: 0,
  name: '',
  date: new Date(),
  status: '',
  statusDetails: ticket
 ]}
}

This is the object that I'm trying to add:

const ticket = [
  { ticketNumber: '', duration: '', rootCause: 'rootCause', impact: '', outageDetails: '' }
]

My Table that is being rendered:

          <Table>

            ...

            <Table.Body>
              {this.state.sites.map((site, id) =>
                <Table.Row key={id}>
                  <Table.Cell><Checkbox slider /></Table.Cell>
                  <Table.Cell>{site.name}</Table.Cell>
                  <Table.Cell>
                    <Dropdown fluid button compact selection
                      placeholder='Status'
                      defaultValue={'ok'}
                      options={statusOptions}
                      onChange={this.handleStatusChange.bind(this, id)}
                    />
                  </Table.Cell>
                  <Table.Cell />
                  <Table.Cell />

                  <Table.Cell>
                    <Table>
                      <Table.Body>
                        {site.statusDetails.map(item =>
                          <Table.Row key={item}>
                            <Table.Cell>
                              <Input placeholder='Ticket #' onChange={this.handleCherwellChange.bind(this, id)/>
                            </Table.Cell>
                            <Table.Cell />
                            <Table.Cell>
                              <Form.Dropdown fluid button compact selection
                                placeholder='rootCause'
                                defaultValue={'rootCause'}
                                options={rootCauseOptions}
                                onChange={this.handleRootCauseChange.bind(this, id)}
                              />
                            </Table.Cell>
                            <Table.Cell><Input placeholder='Impact' onChange={this.handleImpactChange.bind(this, id)} /></Table.Cell>
                            <Table.Cell><Input placeholder='Outage Details' onChange={this.handleOutageDetailsChange.bind(this, id)} fluid size='mini' /></Table.Cell>
                          </Table.Row>
                        )}
                      </Table.Body>
                    </Table>
                  </Table.Cell>

                  <Table.Cell collapsing><Button icon='plus' onClick={this.addStatusDetail(id)} /></Table.Cell>
                </Table.Row>
              )}
            </Table.Body>

            ...

          </Table>

I'm not going to put all my property value handler methods but here's two of them that's working. The first handler method that that's within the first mapping:

handleStatusChange = (id, e, { value }) => {
    this.setState(Object.assign(this.state.sites[id], { status: value }));
  }

And my second handler within the the nested mapping:

  handleImpactChange = (id, e, { impact }) => {
    const newSites = this.state.sites.map(site => {
      if (site.id !== id) return site;
      return { ...site, statusDetails: [...site.statusDetails, { impact }] };
    });
    this.setState({ sites: newSites });
  }

Now the issue is in my onClick method that is trying to insert a new ticket into a site's statusDetail. I tried three different onClick methods:

  addStatusDetails = (id) => {
    this.setState({ sites: [...this.state.sites[id].statusDetails.concat(ticket)] });
  }

  addStatusDetails = (id) => {
    this.setState((prevState) => {
      const { sites } = prevState;
      sites[id].statusDetails.push(
        Object.assign({}, { ...sites[id].statusDetails, ticket })
      );
      return { sites };
    })
  }

  addStatusDetails = (id) => {
    const { sites } = this.state;
    const newStatusDetails = sites[id].statusDetails;
    newStatusDetails.push(ticket);
    this.setState(Object.assign(sites[id], { statusDetails: newStatusDetails }))
  }

Using each one is giving me very different issues so I'm having a hard time pin-pointing

First onClick method is giving me this issue:

TypeError: Cannot read property 'map' of undefined

Both the second and third onClick methods are giving me:

Invariant Violation: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

0 个答案:

没有答案