[React] CMultiSelect: if options change, the element is not updated
- Operating system and version: Windows 10, MacOS Catalina
- Browser and version: Chrome, Firefox
If the prop options change, the component is not redrawn.
Test case
Here is a simple app that has a button and a component Component with a CMultiSelect. When the button is pressed, it randomly selects 3 universities from an array of 10 names, and renders the CMultiSelect in Component with these 3 random names.
However, when the button is pressed, the component Component is redrawn, but CMultiSelect is not.
App.tsx
import React from "react";
import Component from "./Component";
const data = [
"Garrett College",
"Cecil College",
"City Colleges of Chicago-Malcolm X College",
"University of Missouri - Saint Louis",
"Kilgore College",
"Rainy River Community College"
];
function App() {
const [uni, setUni] = React.useState<any[]>([]);
const fetchUniversities = function () {
const sliced = [];
for (let i = 0; i < 3; i++) {
let rndIndex = Math.random() * (data.length - 1);
rndIndex = Math.round(rndIndex);
sliced.push({
text: data[rndIndex],
value: i
});
}
setUni(sliced);
};
return (
<>
<div className="App">
<button onClick={() => fetchUniversities()}>Update values</button>
</div>
<div>
<Component values={uni} />
</div>
</>
);
}
export default App;
Component.tsx
import React from "react";
import { CMultiSelect } from "@coreui/react-pro";
const Component = (props: any) => {
console.log(props.values);
return <CMultiSelect options={props.values} />;
};
export default Component;
The problem is in the code of the CMultiSelect.tsx:
This part
useEffect(() => {
const selected = _options && getSelectedOptions(_options);
selected.sort((a: Option, b: Option) => {
if (typeof a.order === "undefined") {
return -1;
}
if (b.order && a.order > b.order) return 1;
if (b.order && a.order < b.order) return -1;
return 0;
});
setSelected(selected);
}, [_options, options]);
is missing an effect to update the _options when the options change. Also the effect depends on options although the callback does not depend on options. So the correct code would be:
useEffect(() => {
setOptions(options);
}, [options]);
useEffect(() => {
const selected = _options && getSelectedOptions(_options);
selected.sort((a: Option, b: Option) => {
if (typeof a.order === "undefined") {
return -1;
}
if (b.order && a.order > b.order) return 1;
if (b.order && a.order < b.order) return -1;
return 0;
});
setSelected(selected);
}, [_options]);
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions
Any news/hint on how to modify the source code of CMultiSelect.tsx @lucagalbu @mrholek? I've just stumbled upon the same issue...
Will be fixed in the next release.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions