Each child in a list should have a unique “key” prop in React : learnprogramming

Hello, I am fighting to get rid of this error from the console:

react_devtools_backend.js:4026 Warning: Each child in a list should have a unique “key” prop.

Check the render method of `RockfonDropdownFilterResponsive`. It was passed a child from RockfonDropdownFilter. See https://reactjs.org/link/warning-keys for more information.

at RockfonDropdownFilterResponsive (webpack-internal:///./app/scripts/core/views/react/O89-product-filtered-list/components/product-filter.tsx:32:20)

at div

at RockfonDropdownFilter (webpack-internal:///./app/scripts/core/views/react/O89-product-filtered-list/components/product-filter.tsx:87:76)

at div

at form

at div

at ProductFilterContainerResponsive (webpack-internal:///./app/scripts/core/views/react/O89-product-filtered-list/components/product-filter-container.tsx:49:76)

at ProductFilterContainer

at div

at RockfonFilteredProductListComponent (webpack-internal:///./app/scripts/core/views/react/O89-product-filtered-list/RockfonFilteredProductList.tsx:51:80)

at RockfonFilteredProductList

at Provider (webpack-internal:///./node_modules/react-redux/es/components/Provider.js:16:20)

As I understand, this error is caused by lack of key prop in the map function, but I have added it, and yet I am still getting it, here is my code:

const RockfonFilteredProductListComponent = (props: RockfonProductFilterResultViewModel): ReactElement => {
    return <div className="O89-2-product-filter container">
        <ProductFilterContainer
            isGrid={isGrid}
            resultsCount={resultsCount}
            setIsGrid={setIsGrid}
            texts={props.texts}
            toggleFilterView={toggleFilterView}
        />

        <div className={isGrid === true ? 'grid' : 'list' }>
            {products ? <ProductList
                loadingState={loadingState}
                texts={props.texts}
                hideResult
                scrollLoading
                clearFilters={() => dispatch(resetFilters())}
                loadMore={() => dispatch(requestSearch(false))}
                totalCount={resultsCount}>
                {[...products].sort((a, b) => { if (sortProducts === 'By Name') { return a.name.localeCompare(b.name); } else { return a.name.localeCompare(a.name); } }).map((product) => isGrid
                    ? <ProductCard key={product.id}
                        {...CreateProductCardPropsFromProduct(product, props.showDownloadButtonOnProductCards, props.downloadFileText, props.texts)}
                    />
                    : <ProductListCard key={product.id}
                        {...CreateProductCardPropsFromProduct(product, props.showDownloadButtonOnProductCards, props.downloadFileText, props.texts)}
                    />
                )}
                <div className={isGrid ? 'O96-1-product-card-list__cards' : 'hidden'} />
            </ProductList> :
                <div className="loading-container"><div className="loader is-absolute-centered is-loading" /></div>
            }
        </div>
    </div>
}

export const RockfonFilteredProductList = (props) => {

    return <RockfonFilteredProductListComponent  {...props} />
};

RockfonDropdownFilterResponsive:

const RockfonDropdownFilterResponsive = (props: PropsWithChildren<ProductFilterPresentationProps>): ReactElement => (
	<div className="filterDropdownContainer">
		<div>
			<div
				role="listbox"
				className={props.isOpen ? 'btn-dropdown is-open' : 'btn-dropdown'}
				onClick={props.isOpen ? props.handleClose : props.handleOpen}
				tabIndex={0}
			>
				<span className="filter-name" title={props.filterTitle}>{props.filterTitle}</span>
				
			</div>
			<AnimateHeight className="filter" contentClassName="filter-content" height={props.height} duration={300}>
				{props.children && <>{props.children} <div className="divider" /></>}

				<div className="filter__option-title">{props.optionsTitle}</div>
				{props.filterRows.length > 0 && <div className="filter-scrollbar">{props.filterRows}</div>}
				{props.filterRows.length === 0 && (
					<div className="no-filters">{props.noFiltersAvailableLabel}</div>
				)}
			</AnimateHeight>
		</div>	
		<div className="filter-item">
			<div
				role="listbox"
				className={props.isOpen ? 'btn-dropdown is-open' : 'btn-dropdown'}
				onClick={props.isOpen ? props.handleClose : props.handleOpen}
				tabIndex={0}
			>
				<span className="filter-name" title={props.filterTitle}>
					{props.filterTitle}{props.selectedOptions.length > 0 && <sup>({props.selectedOptions.length})</sup>}
				</span>
				
			</div>
			<AnimateHeight height={props.height} duration={300}>
				<div className="filter">
					{props.children}
					{props.children && <div className="divider" />}
					{props.filterRows.length > 0 && (
						<div className="filter-scrollbar">
							{props.filterRows}
						</div>
					)}
					{props.filterRows.length === 0 && (
						<div className="no-filters">{props.noFiltersAvailableLabel}</div>
					)}
				</div>
			</AnimateHeight>
		</div>
	</div>
)

export const RockfonDropdownFilter = (props: PropsWithChildren<ProductFilterProps>): ReactElement => {
	

	const hasGroups = props.groups && props.groups.length > 0;
	const groupsOnOptions: string[] = props.options.map((f) => f.group).filter((g) => g) as string[];
	const isAnyFilterWithGroup =
		hasGroups && groupsOnOptions.some((f) => props.groups!.map((g) => g.value).includes(f));

	let filterRows = [];

	if (isAnyFilterWithGroup) {
		const groupedFilters = props.isMobile
			? generateGroupFiltersMobile(props.groups!, displayedOptions, props.selectedOptions, openTabIndex, setOpenTabIndex, handleFilterRowChange, props.orderSettings)
			: generateGroupFilters(props.groups!, displayedOptions, props.selectedOptions, handleFilterRowChange, props.orderSettings)
		filterRows.push(groupedFilters);
	}
	else {
		filterRows = generateFilterRows(displayedOptions, props.selectedOptions, props.orderSettings, handleFilterRowChange);
	}

	const presentationProps: ProductFilterPresentationProps = {
		selectedOptions: props.selectedOptions,
		filterTitle: props.filterTitle,
		filterRows,
		height,
		handleClose: props.handleClose,
		handleOpen: props.handleOpen,
		optionsTitle: props.optionsTitle,
		isOpen: props.isOpen,
		noFiltersAvailableLabel: props.noFiltersAvailableLabel
	}
	return <div ref={ref}>
		<RockfonDropdownFilterResponsive {...presentationProps}>{props.children}</RockfonDropdownFilterResponsive>
	</div>

Any ideas what is causing this warning?

Leave a Comment