I want to make a highly reusable react component with a unique pattern. Assume this contact list was produced by another team; we can't change the components, and it follows the structure shown below.
<Component>
<Child1 key="child1" />
<Child2 key="child2" />
<Child3 key="child3" />
</Component>
Sample ContactList Component:
<ContactList key="contact-list">
<ContactList.Header key="contactlist-header" />
<ContactList.Body key="contactlist-body" />
<ContactList.Footer key="contactlist-footer" />
</ContactList>
I'd like to offer choices for customising the contact-list component, such as
- Add any component anywhere in contact list
- Remove component based on "key" value
- Replace entire component
I'd like to expose some APIs similar to this.
UI.ContactList.remove("contactlist-footer")
// removed from ContactList and stored in variable for later use
UI.ContactList.add(<CustomContactListFooter/>)
// add Component to ContactList and stored in variable for later use
Where UI is some Namespace / Class
So I need a wrapper component that allows me to manipulate ContactList's children based on above api, let say UI.ContactList.remove("contactlist-footer")
and assume remove API store the data in this variable _removeRequest = ['contactlist-footer']
while rendering component I don't want to show this component <ContactList.Footer key="contactlist-footer">, I can able to do with in ContactList component by manipulate like this
High level idea:
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>
}
This not possible because we are not allowed to modify ContactList component.
<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>
From parent component how do manipulate children of ContactList ? Any thoughts will be helpful