【问题标题】:Best way to pass in a React component?传递 React 组件的最佳方式是什么?
【发布时间】:2019-07-17 23:06:33
【问题描述】:

我希望获得一些关于最佳实践/设计模式的建议,用于将一个组件传递给另一个组件。我的示例是,我有一个页面,该页面具有一个列表组件,该组件遍历地图并呈现项目详细信息组件。我想重用这个列表组件,但是当它在不同的页面上时,使用不同的项目详细信息组件呈现数据。一个要求是,子组件将列表项作为道具进行渲染。

我的第二个问题是,这个子组件有一个可以自行删除的按钮。这应该是从“页面”组件或列表组件传入的回调函数吗?

【问题讨论】:

    标签: reactjs typescript design-patterns


    【解决方案1】:

    对于问题的第一部分,我建议使用儿童道具(在官方文档中称为composition)。

    例如

    function MyPage () {
        return <MyList>
            <MyItem name='item1'/>
            <MyItem name='item2'/>
        </MyList>
    }
    

    MyList 组件看起来像

    function MyList (props) {
        return <div>This is list!
            {props.children}
        </div>
    }
    

    props.children 将包含存在于&lt;MyList&gt; 和&lt;/MyList&gt; 标记之间的所有元素。 (在上面的例子中,它们是&lt;MyItem name='item1'/&gt; 和&lt;MyItem name='item2'/&gt;)。您还可以使用React.children 操作来自MyList 组件的儿童道具。

    对于您问题的第二部分,一般状态应为lifted up。这种方法在大多数情况下都有帮助。它应该移动多高取决于几个因素。例如,如果您要从后端查询列表项并将修改后的列表传递给后端,这可以在MyList 组件中完成。但是,如果您将在其他组件中使用列表项,例如在左侧菜单中,以显示收藏夹,最好将状态提升到 Page 组件。

    【讨论】:

    • 嘿!谢谢!这正是我一直在寻找的,并且对我有很大帮助。
    【解决方案2】:

    如果项目详细信息组件在所采用的道具方面都相同,那么最简单的方法是将组件类型作为道具传递给列表。

    就第二个问题而言,没有黄金法则,它是对您的组件真正有意义的任何东西。不过,根据您的描述,听起来您的列表组件应该是container,并且应该管理删除(也可能还有加载),例如

    const AnchorListItem = ({ onDelete, id, text }) => (
      <li>
        <a data-id={id} onClick={onDelete}>{text}</a>
      </li>
    );
    const ButtomListItem = ({ onDelete, id, text }) => (
      <li>
        <button data-id={id} onClick={onDelete}>{text}</button>
      </li>
    );
    class List extends React.Component {
      handleDeleteItem = e => {
        // Delete item (you can grab ID from e.target.dataset.id)
      }
      render() {
        const { data, component: Item } = this.props;
        const items = data.map((x, i) => <Item key={i} {...x} onDelete={handleDeleteItem} />);
        return <ul>{items}</ul>;
      }
    };
    const PageA = () => <List component={AnchorListItem} data={...} />;
    const PageB = () => <List component={ButtonListItem} data={...} />;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-01
      • 2014-02-12
      • 1970-01-01
      • 2013-12-29
      • 2019-04-22
      • 2012-11-27
      • 1970-01-01
      • 2021-11-01
      相关资源
      最近更新 更多