Форма реакции, для отправки объекта, который затем помещается в массив

#javascript #arrays #forms #reactjs #submit

#javascript #массивы #формы #reactjs #Отправить

Вопрос:

Я новичок в React и не уверен, как это сделать.

У меня есть массив объектов, которые я сопоставил и отобразил в моем представлении. Что я хочу сделать, так это настроить форму, которая будет передавать значения каждого поля соответствующим свойствам нового объекта, но я не уверен, как это сделать.

Вот мои исходные данные, которые отображаются в представлении:

 contactArray = [
  {
    name: 'John'
    email: 'john@email.com'
    number: 111-111-111
  },
  {
    name: 'Dave'
    email: 'dave@email.com'
    phone: '222-222-222'
  }
]
  

Тогда у меня есть форма:

 class InputForm extends Component {
  render() {
    return (   
        <form>
          <input type='text' onChange={this.handleChange}/>
          <input type='text' onChange={this.handleChange}/>
          <input type='text' onChange={this.handleChange}/>
          <button type='submit' onSubmit={this.handleSubmit}>SUBMIT</button>
        </form>
    ) 
  }
  

Тогда я предполагаю, что я объявляю состояние следующим образом:

 constructor(props) {
  super(props);
  this.state = {
    name: '',
    email: '',
    phone: ''
  }
}
  

Затем функция отправки, с которой я действительно не знаю, как обращаться…

 handleSubmit() {
  // not sure about this...
  this.setState({
    name: // ????
    email: // ????
    phone: // ????
  })
}
  

И затем я хочу очистить форму отправки, а также объект, который используется для отправки нового объекта, который теперь находится в массиве (надеюсь, это имеет смысл …)

Итак, я даже не уверен, как использовать state в этом сценарии, но в конечном итоге я хочу, чтобы push() новый объект отображался в массиве со всеми свойствами, поскольку они были заполнены в форме.

Извините, я не могу быть более полным с моей работой до этого момента, но, по крайней мере, оценил бы некоторые указания на это!

Комментарии:

1. Пожалуйста, добавьте update раздел из вашего вопроса в качестве комментария к ответу Пранеша. Ответы на ответы не должны публиковаться в самом вопросе, но должны быть опубликованы / обсуждены в разделе комментариев к соответствующим опубликованным ответам.

Ответ №1:

Насколько я понимаю, вы хотите подтолкнуть новых людей к существующим contactArray ? Я поделюсь своим способом сделать это. Посмотрите:

 const contactArray = [
{
    name: 'John',
    email: 'john@email.com',
    phone: '111-111-111'
  },
  {
    name: 'Dave',
    email: 'dave@email.com',
    phone: '222-222-222'
  }
];

class Form extends React.Component {

  constructor() {
    super();
    this.state = {
      contacts: contactArray
    };
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleSubmit(e) {
    e.preventDefault();
    const
    { contacts } = this.state,
    name = this.refs.name.value,
    email = this.refs.email.value,
    phone = this.refs.phone.value;
    this.setState({
      contacts: [...contacts, {
        name,
        email,
        phone
      }]
    }, () => {
      this.refs.name.value = '';
      this.refs.email.value = '';
      this.refs.phone.value = '';
    });
  }

  render() {
    const { contacts } = this.state;
    console.log('message',this.state.contacts);
    return (   
      <div>
        <h2>Add Someone</h2>
        <form onSubmit={this.handleSubmit}>
          <input type="text" ref="name" placeholder="name" />
          <input type="text" ref="email" placeholder="email" />
          <input type="text" ref="phone" placeholder="phone" />
          <button type="submit">Submit</button>
        </form>
        <h2>Exsiting contacts:</h2>
        <ul>
          {contacts.map((contact) => 
           <li>{`Name: ${contact.name} Email: ${contact.email} Phone: ${contact.phone}`}</li>
          )}
        </ul>
      </div>
    ) 
  }
}

ReactDOM.render(<Form />, document.getElementById('root'));
  

Итак, первое, что мы делаем, это сохраняем contactArray в нашем фактическом компоненте, где мы собираемся его использовать, затем мы декалируем и привязываем наш handleSubmit I, который я использую refs для входных данных, чтобы получить их значение. this.setState ({ contacts: [...contacts] , { Object }); Здесь мы используем оператор распространения ES6, чтобы перевести все существующие контакты в наше новое состояние и добавить новый контакт. { name, email, phone } Это точно так же, как делать { name:name, email:email ...} это просто коротко, this.setState({}, () => { Callback! }); в функции обратного this.setState({}); вызова я собираюсь очистить входные значения. Живая демонстрация: http://codepen.io/ilanus/pen/qaXNmb

Вот еще один способ, которым вы можете это сделать, тот же результат, другой подход.

 const contactArray = [
  {
    name: 'John',
    email: 'john@email.com',
    phone: '111-111-111'
  },
  {
    name: 'Dave',
    email: 'dave@email.com',
    phone: '222-222-222'
  }
];

class Form extends React.Component {

  constructor() {
    super();
    this.state = {
      contacts: contactArray,
      newContact: {
       name: '',
       email: '',
       phone: ''
     }
    };
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleInput = this.handleInput.bind(this);
  }

  handleSubmit(e) {
    e.preventDefault();
    const { contacts, newContact } = this.state;
    this.setState({
      contacts: [...contacts, newContact],
    }, () => {
      for (let val in newContact) {
        newContact[val] = ''; // Clear the values...
      }
      this.setState({ newContact });
    });
  }

  handleInput(e, element) {
    const { newContact } = this.state;
    newContact[element] = e.target.value;
    this.setState({ newContact });
  }

  render() {
    const { contacts, newContact } = this.state;
    const { name, email, phone } = newContact;
    return (   
      <div>
        <h2>Add Someone</h2>
        <form onSubmit={this.handleSubmit}>
          <input type="text" value={name} onChange={e => this.handleInput(e, 'name')} placeholder="name" />
          <input type="text" value={email} onChange={e => this.handleInput(e, 'email')} placeholder="email" />
          <input type="text" value={phone} onChange={e => this.handleInput(e, 'phone')} placeholder="phone" />
          <button type="submit">Submit</button>
        </form>
        <h2>Exsiting contacts:</h2>
        <ul>
          {contacts.map((contact) => 
           <li>{`Name: ${contact.name} Email: ${contact.email} Phone: ${contact.phone}`}</li>
          )}
        </ul>
      </div>
    ) 
  }
}

ReactDOM.render(<Form />, document.getElementById('root'));
  

Живая демонстрация: http://codepen.io/ilanus/pen/LRjkgx

Я настоятельно рекомендую использовать первый пример. поскольку его производительность будет лучше 🙂

Комментарии:

1. Спасибо. Я читал, что вам следует избегать использования ссылок, где это возможно — я никогда их не использовал, поэтому не уверен в их ограничениях… можете ли вы что-нибудь прояснить по этому поводу?

2. @Paulos3000 почему бы не использовать ссылки? Я добавил еще один пример суммирования формы без ссылок.

3. Я не уверен, почему именно, я прочитал это здесь — tutorialspoint.com/reactjs/reactjs_refs.htm — Я просто хотел лучше понять, когда они уместны, а не полагаться на них и позже обнаруживать их недостатки.

4. codepen сломан у вас есть другой пример

Ответ №2:

Вам не нужно устанавливать state для всех inputs . Если вы это сделаете, это будет проблемой, когда у вас будет больше input полей. Смотрите Приведенную ниже скрипку, в которой я использовал один state для хранения всех контактов. Когда вы нажимаете кнопку отправки, он получает все значения из input и сохраняет их в state . Надеюсь, это поможет!

Скрипка: http://jsfiddle.net/Pranesh456/8u4uz5xj/1 /

[ОБНОВЛЕНИЕ]

  1. e.value = null очистит значение внутри формы. Таким образом, вы сможете сбросить всю форму.
  2. slice() используется для создания копии массива в состоянии. Поскольку присвоение массива является a reference исходному массиву, любая операция над новым массивом также будет отражаться в исходном массиве.

Пример:

 a = [1,2,4]
b = a
b.push(7)
console.log(b) //prints [1,2,4,7]
console.log(a) //also prints [1,2,4,7]
  

Но

 b = a.slice() //creates a copy of a
b.push(7)
console.log(b) //prints [1,2,4,7]
console.log(a) //also prints [1,2,4]
  

Подробнее о срезе

Делая это, вы не будете изменять существующее состояние, что является хорошей практикой.

Надеюсь, это поможет!!

Комментарии:

1. Спасибо. Хотя JSFiddle — это более или менее то, что я вставил в свой OP… Вы отправили неправильную ссылку?

2. @Paulos3000 Привет! Извините! Обновлена ссылка.

3. Действительно полезно — спасибо. Пожалуйста, взгляните на мое обновление, в вашем коде есть пара вещей, в которых я не был уверен…

4. Просто примечание — альтернативный способ очистки элементов формы после отправки — это вызвать .reset() элемент формы при отправке. Я только что узнал об этом и подумал, что это может быть полезно для всех, кто сталкивается с этим сценарием…

5. @Paulos3000 Это помогает! Спасибо!