React表单,提交对象,然后将其推送到数组

时间:2016-09-29 11:49:30

标签: javascript arrays forms reactjs submit

我是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: // ????
  })
}

然后我想清除提交表单,以及用于推送新对象的对象,现在在数组中(我希望这有意义......)

所以,我甚至不确定如何在这种情况下使用状态,但最终我想push()新对象到渲染的数组,其中包含所有属性,因为它们已在形式。

对不起,我的工作到目前为止还不够完整,但至少会对此有所了解!

2 个答案:

答案 0 :(得分:4)

根据我的理解,您希望将新人推向现有的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进行decalre并绑定我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)

您不需要为所有state设置inputs。如果您这样做,当您有更多input字段时,它会成为一个问题。请参阅下面的小提琴,其中,我使用了一个state来存储整个联系人。当您按下提交按钮时,它会获取input中的所有值并将其保存到state。希望它有所帮助!

小提琴:http://jsfiddle.net/Pranesh456/8u4uz5xj/1/

<强> [UPDATE]

  1. e.value = null将清除表单中的值。这样,您就可以重置整个表单。
  2. slice()用于制作状态中数组的副本。由于数组的赋值是原始数组的reference,因此新数组上的任何操作也将反映在原始数组中。
  3. 示例:

    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]
    

    有关slice

    的更多详情

    通过这样做,你不会改变现有状态,这是一种很好的做法。

    希望有所帮助!!