2017-10-12 53 views
3

我目前正在尝试创建一个按钮onclick被附加到DOM元素的父组件。但是,我有一个问题得到初始循环工作。下面是我在做什么,反应试图循环通过状态对象

class GenerateInvoice extends Component { 

    constructor(props) { 
    super(props); 
    this.state = { 
     'invoice': { 
     'items' : {} 
     } 
    }; 

    this.onAddChild = this.onAddChild.bind(this); 
    } 

    render() { 
    const children = []; 
    for (var i = 0; i < Object.keys(this.state.invoice.items); i += 1) { 
     children.push(<InvoiceItemForm key={i} number={i} />); 
    }; 
    return(
     <div> 
     <a href="" onClick={this.onAddChild}>Add New Item</a> 
     {children} 
     </div> 
    ) 
    } 

    onAddChild = (e) => { 

    e.preventDefault(); 
    let invoice = this.state.invoice.items; 
    this.setState({ invoice : {'id' : 'INV001'} }); 
    } 


} 

export default GenerateInvoice ; 

然而,当我的客户端与它onAddChild回调的按钮,我得到

无法转换未定义或为空反对

为什么会这样是?

这里是我的测试项目中的链接,

https://codesandbox.io/s/0qx9w1qrwv

+0

你的状态对象键不必是字符串 –

+1

@KarlTaylor:他们不是。 *属性名*以字符串形式给出,true,这是可选的,但是无害的。 –

+0

请使用Stack Snippets('[<>]'工具栏按钮)使用** runnable ** [mcve]更新您的问题。 Stack Snippets支持React,包括JSX; [这是如何做一个](http://meta.stackoverflow.com/questions/338537/)。 –

回答

2

您在这里覆盖的状态:

let invoice = this.state.invoice.items; 
this.setState({ invoice : {'id' : 'INV001'} }); 

后打电话给你的状态会

{ invoice: {'id': 'INV001'} } 

物品属性将会消失。

如果你想添加一个项目,像这样的工作:

let invoice = this.state.invoice; 
// creates an updated version of the items without changing the original value 
let updatedItems = invoice.items.concat({'id': 'INV001'}); 
// creates a new version of the invoice with the updated items 
let updateInvoice = { ...invoice, items: updatedItems }; 
// update the invoice on the state to the new version 
this.setState({ invoice }); 
+0

这是假设项目被更改为数组T.J. Crowgers建议上面 – wgcrouch

+0

更改为数组,它工作的很棒:),但我想要一些关于为什么我的循环效率低下的输入? – Udders