【问题标题】:Move method from one component to another in React and still be able to use in original在 React 中将方法从一个组件移动到另一个组件,并且仍然可以在原始组件中使用
【发布时间】:2016-08-27 18:46:17
【问题描述】:

我正在使用 React 和 ES6 创建一个小型联系人应用程序。我在组件的渲染函数中显示了一些数据 - 有关原始结构,请参阅下面问题的链接...

How to specify a key for React children when mapping over an array

但是,因为我也在同一页面上放置了一个表单,并且我需要更新状态中的数据,所以我不得不将数据移动到更高级别的组件。

现在我在遍历组件时遇到问题,因此我的原始联系人列表显示在左侧。我不得不删除联系人列表组件的渲染函数中的大部分内容,因为它完全破坏了构建。

首先,这是带有表单的地址簿组件 - 这是有效的,既从状态中拉入我最初的 3 个联系人,然后将新联系人从表单连接到数组。 (此处仍需要清理代码以使 UI 正常工作...)

import React from 'react';
import ContactList from './contact-list.jsx';
import ContactForm from './contact-form.jsx';
import ShortContact from './short-contact.jsx';

class AddressBook extends React.Component {

constructor() {
    "use strict";
    super();

    this.state = {
        showContacts: true,
        contacts: [
    {
        id: 1,
        fName: "aaa",
        lName: "aaaaa",
        imgUrl: "http://brainstorminonline.com/wp-content/uploads/2011/12/blah.jpg",
        email: "aaa@aaaa.com",
        phone: "999999999999"
    },
    {
        id: 2,
        fName: "bbbbb",
        lName: "bbbbbbb",
        imgUrl: "https://media.licdn.com/mpr/mpr/shrinknp_200_200/bbb.jpg",
        email: "bbb@bbb-bbb.com",
        phone: "888888888888"
    },
    {
        id: 3,
        fName: "Number",
        lName: "Three",
        imgUrl: "http://3.bp.blogspot.com/-iYgp2G1mD4o/TssPyGjJ4bI/AAAAAAAAGl0/UoweTTF1-3U/s1600/Number+3+Coloring+Pages+14.gif",
        email: "three@ccccc.com",
        phone: "333-333-3333"
    }
];
    };

}




render() {
    "use strict";
    return (
        <div className="row address-book">

            <div className="col-md-6">
                <ContactList  />
            </div>
            <div className="col-md-6">

                <button className='btn' id="contact-submit-button" type="submit" value="Create Contact">Create New Contact </button>



                <div>
                    <ContactForm  addContact={this._addContact.bind(this)}/>
                </div>
            </div>
        </div>

    );

}

_addContact (fName, lName, company, email, phone, imgURL) {
    "use strict";
    const contact = {
        id: this.state.contacts.length + 1,
        fName,
        lName,
        company,
        email,
        phone,
        imgURL
    };
    this.setState({ contacts: this.state.contacts.concat([contact]) });
}

_getContacts() {
    "use strict";
    return contactList.map((contact) => {
        "use strict";
        return (
            <ShortContact contact={contact} key={contact.id}/>)
    });
}

_getContactsTitle (contactCount) {
    "use strict";
    if(contactCount === 0) {
        return 'No Contacts';
    } else if (contactCount === 1) {
        return '1 contact';
    } else {
        return `${contactCount} contacts`;
    }
}

}

export default AddressBook;

但是,底部的 2 个方法 _getContacts 和 _getContactsTitle 是我的 ContactForm 组件中需要的 - 就是这个:

import React from 'react';
import ShortContact from './short-contact.jsx';




class ContactList extends React.Component {



render() {

    const contacts  = this._getContacts();


    return (
        <div>
            <h3>List of Contacts</h3>
            <h4 className="contact-count">{this._getContactsTitle((contacts.length))}</h4>
            <ul className="contact-list">
                {contacts}
            </ul>
        </div>
    );
    }
}

export default ContactList;

通过&lt;ul&gt; 定义联系人以及&lt;h4&gt; 的常量破坏了应用程序,因为您可以看到它引用了来自其他组件的_getContactTitle 方法以及_getContacts 中的{contacts}方法。

我猜我需要做一些事情,比如将它们包装成函数并传递它们——但我已经转过身来,不太明白这在 React 中是如何工作的。欢迎任何帮助。谢谢!

【问题讨论】:

    标签: javascript reactjs ecmascript-6


    【解决方案1】:

    您需要通过 props 向下传递联系人,而不是尝试在父级中构建要传递的联系人列表。我的意思是这个。

    通讯录

    render() {
        "use strict";
        let contacts  = this._getContacts();
    -----------^---------------^----------- get the list in the parent
        return (
            <div className="row address-book">
                <div className="col-md-6">
                    <ContactList contacts={contacts} />
    -------------------------------^-----------^---- important part here
                </div>
                <div className="col-md-6">
                    <button className='btn' id="contact-submit-button" type="submit" value="Create Contact">Create New Contact </button>
                    <div>
                        <ContactForm  addContact={this._addContact.bind(this)}/>
                    </div>
                </div>
            </div>
    
        );
    }
    

    然后在您的 CONTACT LIST 组件中,只需将列表用作道具。

    render() {
        let {contacts} = this.props;
    ------------^--------------^---- its in the props now
        let title = contacts.length > 1 ? `${contacts.length} contacts` : contacts.length === 1 ? '1 contact' : 'No Contacts';
        return (
            <div>
                <h3>List of Contacts</h3>
                <h4 className="contact-count">{title}</h4>
                <ul className="contact-list">
                    {contacts}
                </ul>
            </div>
        );
        }
    }
    

    您可以从这里删除contactTitle 功能。让孩子渲染它,因为它知道数组的长度(因为它在道具中)。

    作为旁注,在您的 _addContact 函数中。而不是创建一个新数组并将其与状态联系人数组连接,只需将新数组推送到当前状态即可。它更好的存储(即不需要创建一个新数组来将新项目组合到数组中)。

    this.setState({ contacts: this.state.contacts.push(contact) });
    

    【讨论】:

    • 再次感谢。道具正是我需要的,我知道但看不到。对于新的结构和语法,我一次只能记住这么多。这里的标题代码也很棒。我最终将 _getContacts 方法移回了我的列表组件,因为我可以使用道具访问数据,并允许我使用它来映射和呈现列表。
    猜你喜欢
    • 1970-01-01
    • 2020-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-09
    • 1970-01-01
    • 2018-05-07
    相关资源
    最近更新 更多