0

I have created a component that can be used for creating a new company record. A modal is opened with a form and the values are linked to the state values. In my situation, it will be possible to create more than one record of a company if the user chooses to add another company. A new company object will be pushed to the company state and the new empty form will be rendered.

This is what I've tried based on this answer:

import { Component } from 'react';
import { Modal, Header, Form, Button, Icon, Tab, Segment } from 'semantic-ui-react';

export default class CompanyCreate extends Component {
  constructor(props) {
    super(props);

    this.state = {
      company: [
        {
          name: '',
          segment: ''
        }
      ]
    };

    this.initialState = this.state;

    this.handleChange = this.handleChange.bind(this);
    this.handleCompanyChange = this.handleCompanyChange.bind(this);
  }

  handleChange = (e, { name, value }) => this.setState({ [name]: value });

  handleCompanyChange = (e, { name, value }) => {
    const index = this.state.company.findIndex((x) => {
      return x[name] === value;
    });
    if (index === -1) {
      console.log('error');
    } else {
      this.setState({
        company: [
          ...this.state.company.slice(0, index),
          Object.assign({}, this.state.company[index], value),
          ...this.state.company.slice(index + 1)
        ]
      });
    }
  };

  render() {
    const { company } = this.state;

    return (
      <Segment>
            {company.map((e, index) => (
              <Form size="large" key={index}>
                <Form.Group>
                  <Form.Input
                    width={6}
                    onChange={this.handleCompanyChange}
                    label="Nome"
                    placeholder="Nome"
                    name="name"
                    value={e.name}
                    required
                  />
                  <Form.Input
                    width={6}
                    onChange={this.handleCompanyChange}
                    label="Segmento"
                    placeholder="Segmento"
                    name="segment"
                    value={e.segment}
                    required
                  />
                 </Form.Group>
              </Form>
            ))}
          </Segment>
    );
  }
}

My problem is that I can't set the company state properly. How can you update the state in relation to the changes in the form fields?

4
  • 1
    Unless for the title there is no question or current problem mentioned? Neither is this a minimal reproducible example, so there is simply to much to implement, before we can try out your current problem Commented Mar 14, 2018 at 23:50
  • Sorry, the question and the code was updated. Please, help me. Commented Mar 15, 2018 at 1:28
  • That's a lot of code to test the update of a simple state. What is working and what is not? Have you checked you can get event.target.value from (e, { name, value })? Commented Mar 15, 2018 at 2:26
  • The first comment says there is not enough code. Now you say it's a lot of code. If it's simple, please ... show me how to do it. If values were the problem, the question would be different. Commented Mar 15, 2018 at 2:35

1 Answer 1

0

Looking for answers, I found the package: immutability-helper. Based on this answer, the problem was solved simply and elegantly.

The solution:

import update from 'immutability-helper';

//...

this.state = {
  company: [
    {
      name: '',
      segment: ''
    }
  ]
};

//...

handleCompanyChange = (e, { name, value, id }) => {
  let newState = update(this.state, {
    company: {
      [id]: {
        [name]: { $set: value }
      }
    }
  });
  this.setState(newState);
};

//...

render() {
const { company } = this.state;

return (
  <Segment>
        {company.map((e, index) => (
          <Form size="large" key={index}>
            <Form.Group>
              <Form.Input
                width={6}
                onChange={this.handleCompanyChange}
                label="Nome"
                placeholder="Nome"
                name="name"
                value={e.name}
                id={index}
                required
              />
              <Form.Input
                width={6}
                onChange={this.handleCompanyChange}
                label="Segmento"
                placeholder="Segmento"
                name="segment"
                value={e.segment}
                id={index}
                required
              />
             </Form.Group>
          </Form>
        ))}
      </Segment>
  );
}
Sign up to request clarification or add additional context in comments.

Comments

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.