在React中将对象从子组件传递给父组件

时间:2016-11-17 12:24:01

标签: javascript reactjs

在做了一些教程并阅读文档之后,我正在尝试设置我的第一个反应项目,以尝试真正理解它是如何工作的。所以我是一个真正的初学者,我有一种感觉,我没有抓住一个基本概念。

我在尝试将对象从子组件传递给它的父组件时遇到问题。我已设法将对象传递给父对象,但无法将其写入父对象的状态。

我可能会以完全错误的方式接近这一点。任何指导都会被批准。

我已经更新了我的代码,现在使用ref将对象传递给父类但是,我假设因为refs只是在呈现HTML之后React的进程,它总是传回我对象数组中的最后一项而不是我希望与每个选择相关联的人。

class AppContainer extends React.Component { //parent Component
  constructor() {
    super();

    this.state = {
      contactsList:
        [
          {id:1, name: 'Tom Brace', phone: '0123456789', address:'fg dfgh dfgh dfgh dfgh', notes: 'sdfdsfasdfasdf asdf as df asdf  sadf a sdfasdf', Quote:''},

         ...

          {id:7, name: 'Dave Johnson', phone: '0123456789', address:'fg dfgh dfgh dfgh dfg', notes: 'sdfdsfasdfasdf asdf as df asdf  sadf a sdfasdf', Quote:''}
        ],
        selectedContact: {id:1, name: 'Tom Brace', phone: '0123456789', address:'fg dfgh dfgh dfgh dfg', notes: 'sdfdsfasdfasdf asdf as df asdf  sadf a sdfasdf', Quote:''}
    }
  }

  render(){
    return(
      <div className="container-fluid">
        <div className="row">
          <div id="sidebar" className="col-xs-12 col-md-3 sidebar">
             <ContactNav updateContact={this._updateContact.bind(this)}
                          contactsList={this.state.contactsList}
                        />
                      </div>
                      <div id="content" className="col-xs-12 col-md-9 main">
                        <Content
                          selectedContact={this.state.selectedContact}
                        />
                      </div>
                    </div>
                  </div>
                );
              };

              _updateContact(obj){
  console.log(obj)
                this.setState({
                selectedContact: obj
              });
              }
            }

            class ContactNav extends React.Component { //child of AppContainer

              render() {
                const contacts = this._getContacts() || [];
                return(
                  <div>
                    <div className="input-group">
                      <input type="text" className="form-control" placeholder="Search for..." />
                      <span className="input-group-btn">
                        <button className="btn btn-default" type="button">Go!</button>
                      </span>
                    </div>
                    <ul className="nav nav-sidebar">
                      {contacts}
                    </ul>
                  </div>
                );
              }
              _handleClick(){
                event.preventDefault();
console.log(this._obj);
                let obj = this._obj
                this.props.updateContact(obj);
              }


              _getContacts() {
                return this.props.contactsList.map((i) => {
                  return (
                    <li key={i.id}>
                      <a href="#" key={i.id} onClick={this._handleClick.bind(this)} ref={(input) => this._obj = i}>
                        {i.name}
                      </a>
                    </li>
                  );
                });
              }
            }

            class Content extends React.Component { //child of AppContainer
              render() {
                return(
                  <div>
                    <h1 className="page-header">{this.props.selectedContact.name}</h1>
                    <h3 className="sub-header">{this.props.selectedContact.phone}</h3>
                    <h6 className="sub-header">{this.props.selectedContact.address}</h6>
                    <h6 className="sub-header">{this.props.selectedContact.notes}</h6>
                  </div>
                );
              }
            }


            ReactDOM.render(
              <AppContainer />, document.getElementById('app')
            );
html, body, #app, .container-fluid, .row {
  height: 100%;
}
.sidebar {
    z-index: 1000;
    display: block;
    padding: 20px;
    overflow-x: hidden;
    overflow-y: auto;
    background-color: #f5f5f5;
    border-right: 1px solid #eee;
		height:100%;
}
.active {
  background-color: blue;
  color: white;
}
<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>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<div id="app">
      </div>

2 个答案:

答案 0 :(得分:3)

您可以将其传递为props。我将举一个简单的例子,将对象从子组件传递给父组件

<强> 方案

我们说我们有多个卡片项目要显示,每个卡片项目都有ID,名称,日期等属性。每个卡片项目都有删除功能/操作,我们可以将此删除操作作为一个组件(它将是项目组件的子组件)让我们看看如何将值传递给子项中的父项。

让我们看一下子组件(删除组件)

/**
 * Delete component
 */

import * as React from 'react';
import { IconButton, Button } from 'react-toolbox/lib/button';


interface IDeleteProps {
    onDeleteClick: (e:boolean) => void;
}


class Delete extends React.Component<IDeleteProps, {}> {

    constructor(props) {
        super(props);
    }
    public onClickTrigger = () => {
        this.props.onDeleteClick(true);
    }
    public render() {
        return (

            <Button icon='inbox' label='Delete' onClick={this.onClickTrigger} flat primary />

        );
    }
}

export default Delete;

在这里你可以看到我们正在尝试检查按钮是否被点击,主要目的是通知父组件(项目组件)进行进一步的处理,这里的onDeleteClick方法被用作{ {1}}将布尔值传递给父组件,现在让我们看一下父组件(项目)

prop

您可以在Item组件中看到,在render方法中调用Delete组件并调用/** * Item component */ import * as React from 'react'; import './styes.scss'; import Edit from '../item/operation/Edit'; import Delete from '../item/operation/Delete'; import View from '../item/operation/View'; const ReactGauge = require('react-gauge').default; interface IItemProps { item: any; onDeleteChangeItem: (id: number) => void; } class Item extends React.Component<IItemProps, {}> { constructor(props) { super(props); } public deleteClickedEvent = (e: boolean) => { if (e === true) { this.props.onDeleteChangeItem(this.props.item.id); } } public render() { const dummyText = 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.'; const itemStyle = { backgroundImage: `url('${this.props.item.url}')` }; return ( <div style={itemStyle} className='AudienceGridItem'> <span className='name'>{this.props.item.id}</span> <span className='name'>{this.props.item.name}</span> <span className='name'>{this.props.item.customerCount}</span> <span className='name'>{this.props.item.lastEdited}</span> <span className='name'>{this.props.item.lastRerun}</span> <ReactGauge value={this.props.item.percentage} width={140} height={70} /> <Edit /> <Delete onDeleteClick={this.deleteClickedEvent} /> <View /> </div> ); } } export default Item; 并将其分配给方法onDeleteClick,在该方法中它检查传递的布尔值并相应地进行。这是我的例子,当我在学习父母的孩子组件互动时我试过反应,希望这有助于你理解到一定程度,如果我没有任何意义请指出我

答案 1 :(得分:2)

在这种情况下不要使用refs。你的ref(this._obj)在你的循环中不断被覆盖。将对项目的引用传递给单击处理程序本身。所以,改变这些:

<a href="#" key={i.id} onClick={this._handleClick.bind(this) } ref={(input) => this._obj = i}>
  {i.name}
</a>

_handleClick(){
  event.preventDefault();
  console.log(this._obj);
  let obj = this._obj
  this.props.updateContact(obj);
}

到这些:

<a href="#" key={i.id} onClick={() => this._handleClick(i) }>
  {i.name}
</a>

_handleClick(obj){
  event.preventDefault();
  this.props.updateContact(obj);
}