#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 /
[ОБНОВЛЕНИЕ]
e.value = null
очистит значение внутри формы. Таким образом, вы сможете сбросить всю форму.slice()
используется для создания копии массива в состоянии. Поскольку присвоение массива является areference
исходному массиву, любая операция над новым массивом также будет отражаться в исходном массиве.
Пример:
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 Это помогает! Спасибо!