Last active
April 18, 2025 17:47
-
-
Save AnkushMalik/38ddaafed5fe380df8abe96e3b273ca7 to your computer and use it in GitHub Desktop.
Design a List component
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Asked to me in Adobe interview (CS-I position); 2025; India | |
// Design a list component | |
// 1. Should allow users to render any kind of data, e.g List of users, List of products, list of names | |
// 2. Should have pagination support with Next/Previous page | |
// | |
// My answer starts here -- | |
// | |
// requirements: | |
// - render the data | |
// - pagination | |
// - can be fetched from server | |
// - <List | |
// children=[{ | |
// id = unique any, | |
// label = string (user.name|product.name) | |
// image? = string (image) | |
// }] | |
// className = ""; | |
// listItem? = {<ListItem/>}; | |
// deleteAction = ()=> void; | |
// deleteIcon? = ReactComponent; | |
// defaultSize? = {25}; | |
// defaultPage = number; | |
// pageChange = (page: Number) => void | |
// /> | |
const ListWrapper = () => { | |
const [listData, setListData] = React.useState([]); | |
const [page, setPage] = React.useState(0); | |
const [pageSize, setPageSize]= React.useState(25); | |
const [maxPageSize, setMaxPageSize]= React.useState(25); | |
const [loading, setLoading] = React.useState(false); | |
const loadPageData = async (page) => { | |
const response = await fetch(`https:/.....url////?page=${page}?pageSize=${pageSize}`); | |
const data = clientSideFilter(response.json()); | |
if(data.maxPageValueFromBackend) | |
setMaxPageSize(data.maxPageValueFromBackend) | |
setListData(data) | |
} | |
React.useEffect(()=>{ | |
loadPageData(page) | |
},[]) | |
return( | |
<div> | |
<List | |
children={listData} | |
pageChange={loadPageData} | |
loading={loading} | |
pageSize={pageSize} | |
maxPageSize={maxPageSize} | |
// ... | |
/> | |
</div> | |
) | |
} | |
const List = (props = { | |
children, | |
className = "", | |
listItem = defaultLibraryComponent, | |
deleteAction = null, | |
deleteIcon = defaultLibraryDeleteIcon, | |
defaultSize = 25, | |
defaultPage = 0, | |
pageChange = null, | |
maxPageSize = null, | |
loading=boolean | false, | |
}) => { | |
// | |
return ( | |
<div className={`my-some-default-library-css-classnames ${props.className}`}> | |
<div loading={<div>...</div>}> | |
{props.children.map(item => | |
<div> | |
{props.listItem? | |
<props.listItem item={item} key={item.id}/> | |
: | |
<defaultLibraryComponent | |
item={item} | |
key={item.id} | |
deleteIcon={deleteIcon || defaultLibraryDeleteIcon} | |
deleteFn={()=>props.deleteAction(item.id)} | |
/> | |
} | |
</div> | |
)} | |
</div> | |
// pagination | |
<pagination | |
page= {defaultPage} | |
maxPageSize = {maxPageSize} | |
pageChange = {props.pageChange} | |
/> | |
</div> | |
) | |
} | |
const Pagination = () => { | |
const [currentPage, SetCurrentPage] = useState(defaultPage); | |
const onPageChange = async (pg) => { | |
await pageChange(pg) | |
SetCurrentPage(pg) | |
} | |
return ( | |
ArrayOfSize(maxPageSize||10).map(e=>{ | |
<div key={e}> | |
{if e==currentPage} highlightedComponent; | |
else: basicPageNumber | |
</div> | |
... | |
}) | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment