I have written two component. One for rendering a list which is used inside it’s parent component hosting the Select
component provided by Material UI.
THe snippets for the both are below.
import React from 'react';
import './index.css';
import { LMFeedTopics } from '@likeminds.community/feed-js-beta';
import { Checkbox, MenuItem } from '@mui/material';
interface TopicListProps {
list: LMFeedTopics[];
checkedList: string[];
}
const TopicList = ({ list, checkedList }: TopicListProps) => {
return (
<>
{list.map((topic: LMFeedTopics) => {
return (
<MenuItem key={topic.Id} value={topic.Id} role="option">
<div className="topicTile">
<Checkbox checked={checkedList.includes(topic.Id)} />
<span>{topic.name}</span>
</div>
</MenuItem>
);
})}
</>
);
};
export default TopicList;
The Parent component is
import React, { useCallback, useEffect, useState } from 'react';
import './index.css';
import { LMFeedTopics } from '@likeminds.community/feed-js-beta';
import { lmFeedClient } from '../../..';
import { Checkbox, FormControl, MenuItem, Select } from '@mui/material';
import TopicList from '../topic-list';
interface TopicFeedDropdownSelectorProps {}
const TopicFeedDropdownSelector = () => {
const [topicList, setTopicList] = useState<any[]>([]);
const [checkedTopicList, setCheckedTopicList] = useState<string[]>([]);
const [page, setPage] = useState<number>(1);
const [searchKey, setSearchKey] = useState<string>('');
const getData = useCallback(async () => {
// Used go get some data with an API call.
}, [page, searchKey]);
useEffect(() => {
getData();
}, []);
return (
<div>
<Select
multiple={true}
IconComponent={() => (
<svg
width="12"
height="16"
viewBox="0 0 12 16"
fill="none"
xmlns="http://www.w3.org/2000/svg">
<path
d="M6.52567 15.7821L11.287 11.0208C11.5775 10.7303 11.5775 10.2591 11.287 9.96863C10.9964 9.67807 10.5254 9.67807 10.2349 9.96863L6.74356 13.4599L6.74356 0.743959C6.74356 0.333115 6.41044 0 5.9996 0C5.58882 0 5.25564 0.333115 5.25564 0.743959L5.25564 13.4599L1.76433 9.96875C1.47377 9.67819 1.00275 9.67819 0.712193 9.96875C0.567032 10.114 0.494303 10.3044 0.494303 10.4948C0.494303 10.6852 0.567032 10.8756 0.712193 11.0209L5.47353 15.7821C5.76409 16.0727 6.23511 16.0727 6.52567 15.7821Z"
fill="#666666"
/>
</svg>
)}
value={checkedTopicList}
onChange={(e: any) => {
console.log(e);
}}>
<TopicList list={topicList} checkedList={checkedTopicList} />
</Select>
</div>
);
};
export default TopicFeedDropdownSelector;
The problem is that the onChange function isn’t getting triggered as long as the list is being rendered inside but if i write the logic inside the parent component it works like a charm.
Why is it so, I want the list to get rendered separately in different component, how can i achieve so?
2
Answers
I am not a pro in react but I think you have to put the input
OnChange
out of the render function because you collect data and these data were been reset again and again. You have to create a static component.I hope that I help you
If you read the MUI Select children props description, it is saying that The MenuItem elements must be direct descendants when native is false. (attaching Screenshot)
Also it is better to create a component for List Item instead of the whole List.
Ex.
Component:
Another Way:
And implement like below:
I hope this helps you understand how MUI Select works. Let me know if you have any questions.