I have a React.js list component that I want to use as a generic list component.
Please see the current list component below:
const RepositoryList = () => {
...
return (
<div className="admin-container">
<div className="adminTitle text-center mb-5 fs-3"></div>
<main>
{ !isLoading && !fetchError &&
<div className="col-6 mx-auto">
<Table striped bordered hover>
<RepositoryListHeader />
<tbody>
{showedRepositories.map((repository) => (
<RepositoryRow
key={repository.id}
record={repository}
formId={newRepositoryFormId}
handleSave={handleSave}
handleDelete={handleDelete} />
))}
...
)
}
export default RepositoryList;
So I want the RepositoryListHeader
and RepositoryRow
to pass to my AdminList
component which would look like
const AdminList = ( {headerEl, rowEl, ...} ) => {
...
return (
<div className="admin-container">
<div className="adminTitle text-center mb-5 fs-3"></div>
<main>
{ !isLoading && !fetchError &&
<div className="col-6 mx-auto">
<Table striped bordered hover>
{headerEl}
<tbody>
{showedRepositories.map((repository) => (
{rowEl}
))}
...
)
}
export default AdminList;
However I can pass the repository.id
, … values (which comes from forEach of showedRepositories
) only in AdminList
component and not in the parent of AdminList
where all the parameter should defined.
For example:
<AdminList
...
rowEl={ <RepositoryRow ??? />} />
Is there any way to resolve this?
I’d appreciate any help please.
you can use one of this ways:
1)Passing data with a render prop :
const AdminList = ( {headerEl, renderRowEl} ) => {
return (
<div className="admin-container">
<div className="adminTitle text-center mb-5 fs-3"></div>
<main>
{ !isLoading && !fetchError &&
<div className="col-6 mx-auto">
<Table striped bordered hover>
{headerEl}
<tbody>
{showedRepositories.map((repository) => (
{renderRowEl(repository)}
))}
...
)
}
const App = () => {
return (
<AdminList
headerEl={<RepositoryListHeader />}
renderRowEl={(repository) => (
<RepositoryRow
key={repository.id}
record={repository}
formId={newRepositoryFormId}
handleSave={handleSave}
handleDelete={handleDelete}
/>
)}
/>
);
};
2)render props as ReactComponent:
const AdminList = ( {headerEl, rowEl} ) => {
const HeaderEl = headerEl
const RowEl = rowEl
return (
<div className="admin-container">
<div className="adminTitle text-center mb-5 fs-3"></div>
<main>
{ !isLoading && !fetchError &&
<div className="col-6 mx-auto">
<Table striped bordered hover>
<HeaderEl />
<tbody>
{showedRepositories.map((repository) => (
<RowEl
key={ repository.id }
record={repository}
formId={newRepositoryFormId}
handleSave={handleSave}
handleDelete={handleDelete}
/>
))}
...
)
}
const App = () => {
return (
<AdminList
headerEl= { RepositoryListHeader }
renderRowEl= { RepositoryRow }
/>
);
};
I don’t think I understand your question correctly. However, I think you can pass the element constructor in the props for
AdminList
instead of the element instance, that way you can pass the props you need from within the component that has access to them. As such:<AdminList rowEl={RepositoryRow} />
and use it insideAdminList
as<rowEl />
(you may need to set the name to start with upper case letter since that’s a requirement for React components’ names.)