在组件

时间:2018-04-15 13:49:05

标签: reactjs

我有一个组件接受另一个包含3个字段的组件,我希望我可以在不同的字段中添加新条目

现在我只能在firstname中添加条目,而我不知道如何为lastname和telegrams添加该条目

如果我只是复制它们,那么只能从一个字段中接受这些值

import React, { Component } from 'react';

class Table extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            data: [],
            dataItems: []
        }
    }

addItem(value) {
    let newListItems = this.state.dataItems.slice();

    newListItems.push(value);
    this.setState({
        dataItems : newListItems
    });
}

render() {
    return (
        <div>
            {this.state.dataItems.map(function (item,index) {
                return (
                    <Hello key={index} firstname={item} lastname={item2} telegram={item3}/>
                );
            }, this)}

            <AddItem addItem={this.addItem.bind(this)} />
        </div>
    )
}
}

class Hello extends React.Component {
    constructor(props) {
        super(props);
    }
    render() {
        return <div className='form__row'>
            <p className='form__input' > firstname: {this.props.firstname} </p>
            <p className='form__input'> lastname: {this.props.lastname} </p>
            <p className='form__input'> telegram: {this.props.telegram} </p>
        </div>;
    }
}

class AddItem extends React.Component{
    handleClick(){
        this.props.addItem(this.item.value);
    }
    render(){
        return (
            <div className='form__row'>
                <div>
                    <label >firstname</label>
                    <input className='form__input'  type="text" ref={item => this.item=item} />
                    <label >lastname</label>
                    <input className='form__input'  type="text" ref={item2 => this.item=item2} />
                    <label >telegram</label>
                    <input className='form__input'  type="text" ref={item3 => this.item=item3} />
                </div>
                <button onClick={this.handleClick.bind(this)}> add new in state</button>
            </div>
        );
    }
}

export default Table;

1 个答案:

答案 0 :(得分:0)

有一些重要的事情你错了。我会为你打破它们:

AddItem组件中,您使用的是不受控制的组件,但在为每个表单字段设置值时会反复覆盖相同的属性this.item。在这种情况下,因为它是最后一个,telegrams值是剩下的最后一个。所以它是唯一被设置的。尝试为同一个变量设置三个不同的值也是一样的。

item.value = 1
item.value = 2
item.value = 3

如果您使用此代码段,则显然项目的唯一值为3。因此,我们首先通过将不同的属性与每个表单相关联来修复此组件:

// AddItem component's render function
render(){
    return (
        <div className='form__row'>
            <div>
                <label >firstname</label>
                <input className='form__input'  type="text" ref={item => this.item=item} />
                <label >lastname</label>
                <input className='form__input'  type="text" ref={item2 => this.item2=item2} />
                <label >telegram</label>
                <input className='form__input'  type="text" ref={item3 => this.item3=item3} />
            </div>
            <button onClick={this.handleClick.bind(this)}> add new in state</button>
        </div>
    );
}

另一方面,我强烈建议给你的三个项目提供有意义的名字。所以我会专门将它们切换到firstNamelastNametelegram

你的handleClick也会遇到同样的问题:你传递了相同的this.item.value,这意味着你只是传递了你的最后一组字段。为了让你传递所有这三个,同时保持其功能相同的格式,你需要创建一个包含所有三个item.value的对象。有了这个改变,它现在应该是这样的:

handleClick(){
  const value = {item: this.item.value, item2: this.item2.value, item3: this.item3.value}
  this.props.addItem(value);
}

最后,在Table组件中,其渲染功能需要进行一些更改。看起来你混淆了你在地图函数中命名的item和你传入的item。再次,你应该找到一个更有意义的变量名称,这样就不会发生。

map函数中的item是您要映射的数组的每个项目。在这种情况下,它只是具有所有三个字段的对象。您实际上想要地图函数的item中的item字段。

       {this.state.dataItems.map(function (item,index) {
            return (
                <Hello key={index} firstname={item.item} lastname={item.item2} telegram={item.item3}/>
            );
        }, this)}

以下是您应用的工作版本:

&#13;
&#13;
class Table extends React.Component{
  constructor (props) {
    super(props);
    this.state = {
      data: [],
      dataItems: []
    }
    
  }
  
  addItem(value) {
    
    let newListItems = this.state.dataItems.slice();
    console.warn(newListItems)

    newListItems.push(value);
    this.setState({
        dataItems : newListItems
    });
  }

  render() {
    return (
      <div>
        {this.state.dataItems.map(function (item,index) {
          return (
            <Hello key={index} firstname={item.item} lastname={item.item2} telegram={item.item3}/>
          );
        }, this)}

        <AddItem addItem={this.addItem.bind(this)} />
      </div>
    )
  } 
}

class Hello extends React.Component {
    constructor(props) {
        super(props);
    }
    render() {
        return <div className='form__row'>
            <p className='form__input' > firstname: {this.props.firstname} </p>
            <p className='form__input'> lastname: {this.props.lastname} </p>
            <p className='form__input'> telegram: {this.props.telegram} </p>
        </div>;
    }
}

class AddItem extends React.Component{
    handleClick(){
      const value = {item: this.item.value, item2: this.item2.value, item3: this.item3.value}
      this.props.addItem(value);
    }
    render(){
        return (
            <div className='form__row'>
                <div>
                    <label >firstname</label>
                    <input className='form__input'  type="text" ref={item => this.item=item} />
                    <label >lastname</label>
                    <input className='form__input'  type="text" ref={item2 => this.item2=item2} />
                    <label >telegram</label>
                    <input className='form__input'  type="text" ref={item3 => this.item3=item3} />
                </div>
                <button onClick={this.handleClick.bind(this)}> add new in state</button>
            </div>
        );
    }
}

ReactDOM.render(
    <Table />,
    document.getElementById('app')
);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
&#13;
&#13;
&#13;