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

Posted

技术标签:

【中文标题】反应表单,提交对象,然后将其推送到数组【英文标题】:React form, to submit object which is then pushed to array 【发布时间】:2017-02-07 17:35:24 【问题描述】:

我是 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() 将新对象添加到呈现的数组中,并在表单中完成所有属性。

抱歉,到目前为止,我的工作还不够完善,但至少会感谢一些关于这方面的建议!

【问题讨论】:

请在您的问题中添加update 部分,作为对 Pranesh 回答的评论。对答案的回复不应发布在问题本身上,而应发布/讨论在发布的相应答案的评论部分。 【参考方案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我使用refs作为输入以获得它们的值。 this.setState ( contacts: [...contacts] , Object ); 这里我们使用 ES6 扩展运算符将所有现有联系人传递到我们的新状态并添加新联系人。 name, email, phone name:name, email:email ... 做的一模一样,只是简写,this.setState(, () =&gt; 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

我强烈建议使用第一个示例。因为它的性能会更好:)

【讨论】:

谢谢。我已经读到你应该尽可能避免使用 refs - 我从来没有使用过它们,所以不确定它们的局限性......你能澄清一下吗? @Paulos3000 为什么不使用参考?我也添加了另一个没有引用的表单求和示例。 我不知道究竟是为什么,我在这里读到了 - tutorialspoint.com/reactjs/reactjs_refs.htm - 我只是想更好地了解它们什么时候合适,而不是依赖它们然后发现它们的缺点。 codepen 坏了还有别的例子吗【参考方案2】:

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

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

[更新]

    e.value = null 将清除表单内的值。这样,您就可以重置整个表单。 slice() 用于在状态下制作数组的副本。由于数组的赋值是 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]

更多关于slice的详情

这样做不会改变现有状态,这是一个很好的做法。

希望对你有帮助!

【讨论】:

谢谢。虽然 JSFiddle 或多或少是我在我的 OP 中放入的内容......您是否发送了错误的链接? @Paulos3000 嘿!对不起!更新了链接。 真的很有帮助 - 谢谢。请看一下我的更新,在你的代码中有几件事我不确定...... 请注意——提交后清除表单元素的另一种方法是在提交时在表单元素上调用.reset()。我刚刚发现了这一点,并认为它可能对面临这种情况的任何人都有用...... @Paulos3000 这很有帮助!谢谢!

以上是关于反应表单,提交对象,然后将其推送到数组的主要内容,如果未能解决你的问题,请参考以下文章

如何执行两个 Axios GET 请求,映射结果然后将其推送到数组?

如果项目位于 javascript 对象中,如何将其推送到数组中 [state.lastValue.push 不是函数]

尽管 if (应该充当过滤器),但所有元素都推入数组

如何将 JSON 对象数组发布到 mongodb?

遍历一个数组,将每个项目添加到一个对象并将其推送到 Javascript 中的数组

如何遍历从 snapshot.val() 收到的数据并根据键将其推送到数组