我希望制作一个高度可重用的React组件,采用独特的模式。假设这个联系人列表是由另一个团队制作的;我们不能更改这些组件,并且它们遵循下面所示的结构。
<Component>
<Child1 key="child1" />
<Child2 key="child2" />
<Child3 key="child3" />
</Component>
示例联系人列表组件:
<ContactList key="contact-list">
<ContactList.Header key="contactlist-header" />
<ContactList.Body key="contactlist-body" />
<ContactList.Footer key="contactlist-footer" />
</ContactList>
我想提供自定义联系人列表组件的选择,例如:
- 在联系人列表中任意位置添加任何组件
- 根据“key”值删除组件
- 替换整个组件
我想要类似于以下API的一些公开接口。
UI.ContactList.remove("contactlist-footer")
// 从ContactList中删除并存储到变量以备后用
UI.ContactList.add(<CustomContactListFooter/>)
// 添加组件到ContactList并存储到变量以备后用
其中UI是某个命名空间/类
所以我需要一个包装组件来允许我基于上述API操作ContactList的子级,比如说 UI.ContactList.remove("contactlist-footer")
并假设删除API将数据存储在此变量中:_removeRequest = ['contactlist-footer']
在呈现组件时,我不想显示此组件 <ContactList.Footer key="contactlist-footer"> ,我可以通过 ContactList 组件内部的操作来实现,例如:
高层次的思路:
function ContactList({children}){
const removeKey = UI.ContactList._removeRequest[0]
const newChildren = React.Children.toArray(children).filter(child => child.key !== removeKey)
return <React.Fragement>{newChildren}</React.Fragement>
}
这是不可能的,因为我们不允许修改ContactList组件。
<Parent>
<ContactList/>
</Parent>
function App() {
return (
<div className="App">
<Parent>
<ContactList />
</Parent>
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
function Parent({ children }) {
console.log(children); // ????? how do we access ContactList's children to alter
return children;
}
function ContactList() {
return (
<React.Fragment>
<ContactListHeader key="contactlist-header" />
<ContactListBody key="contactlist-body" />
<ContactListFooter key="contactlist-footer" />
</React.Fragment>
);
}
function ContactListHeader() {
return <h2>Header</h2>;
}
function ContactListBody() {
return <section>Body Content</section>;
}
function ContactListFooter() {
return <footer>Contact List Footer</footer>;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<body>
<div id="root"></div>
</body>
如何从父组件操作 ContactList 的子组件? 有什么建议吗?