fix: fluentSelect unable to set selected option on load
We are using fluent ui's control via @microsoft/fast-react-wrapper npm package, and when trying to render the FluentSelect with FluentOptions programmatically and setting the selected attribute to conditionally true, it doesn't work. Below is the code snippet we are using :-
import { FluentSelect, FluentOption } from "./fluent-component-wrapper";
interface LocationData {
defaultSelection?: number,
dropDownData: any[];
onLocationChange: Function;
}
const LocationComboBox = (props: LocationData) => {
const drpdownselect = (e: any) => {
props.onLocationChange(e.target.value);
}
const renderSelect = () => {
return (<>
<FluentSelect id="locationDdl" className="fluent-select" onInput={drpdownselect}>
{
props.dropDownData.map((item: any) => <FluentOption selected={item.id === props.defaultSelection} key={item.id} value={item.id}>{item.name}</FluentOption>)
}
</FluentSelect>
</>);
}
return (
<div className="locationcombobox">
<div className="form-label" id="locationDdlLbl">Your location</div>
{renderSelect()}
</div>
);
}
Expected Behaviour: Should set the options as selected when condition item.id === props.defaultSelection is true
Current Behaviour: Shows the first element in the list as selected
Our package.json dependencies :
"dependencies": { "@fluentui/web-components": "^2.5.3", "@microsoft/fast-element": "^1.10.3", "@microsoft/fast-foundation": "^2.46.10", "@microsoft/fast-react-wrapper": "^0.3.11", "@microsoft/mgt-element": "^2.5.2", "@microsoft/mgt-msal2-provider": "^2.5.2", "@microsoft/mgt-react": "^2.5.2", "@microsoft/microsoft-graph-client": "^3.0.2", "@microsoft/microsoft-graph-types": "^2.22.0", "@microsoft/teams-js": "^1.6.0", "@reduxjs/toolkit": "^1.8.3", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.3.0", "@testing-library/user-event": "^13.5.0", "@types/jest": "^27.5.2", "@types/react": "^18.0.15", "@types/react-dom": "^18.0.6", "@types/react-redux": "^7.1.24", "@types/redux": "^3.6.0", "@types/underscore": "^1.11.4", "axios": "^0.27.2", "bootstrap": "^5.1.3", "cross-env": "^7.0.3", "moment": "^2.29.4", "moment-timezone": "^0.5.34", "newTeamsjs": "npm:@microsoft/teams-js@^2.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-redux": "^8.0.2", "react-router-dom": "^6.3.0", "react-scripts": "5.0.1", "reactstrap": "^9.1.1", "redux": "^4.2.0", "redux-persist": "^6.0.0", "typescript": "^4.7.4", "underscore": "^1.13.4", "web-vitals": "^2.1.4" }
@EisenbergEffect Any workaround solution for this?
@radium-v Do you have some time to look into this? At one point in time I think there was an issue with setting the initially selected item. Do you recall anything like that? The React wrapper literally just sets the value of the selected property on the FluentOption element. You have a lot more knowledge of the internals of our select so I thought I'd check with you first.
I'm not familiar with how React rendering handles nested elements, but my first guess is that it could be a pacing condition where the select is created, then the options are added after the select has already initialized. This might cause the select to take the first option as the default selected option.
@iamjanit When you inspect the rendered DOM, does the desired option have the selected attribute?
@radium-v When in inspect window, the selected class is only assigned to the first option. However, I will look into the pacing condition and let you know the outcome.
@radium-v I was able to solve it by using useEffect hook dependent on the default selection. So , it runs after the DOM is painted and is able to set the correct option as selected.
import { useEffect, useState } from "react";
import _ from "underscore";
import { FluentSelect, FluentOption } from "./fluent-component-wrapper";
interface LocationData {
defaultSelection?: string | number,
dropDownData: any[];
onLocationChange: Function;
}
const LocationComboBox = (props: LocationData) => {
const [defaultSelected, setDefaultSelected] = useState<string | number>();
useEffect(() => {
setDefaultSelected(props.defaultSelection);
}, [props.defaultSelection]);
const drpdownselect = (e: any) => {
props.onLocationChange(e.target.value);
}
return (
<div className="locationcombobox">
<div className="form-label" id="locationDdlLbl">Your location</div>
<FluentSelect id="locationDdl" className="fluent-select" aria-labelledby="locationDdlLbl" onInput={drpdownselect}>
{
props.dropDownData.map((item: any) => <FluentOption selected={item.id === Number(defaultSelected)} key={item?.id} value={item?.id}>{item?.name}</FluentOption>)
}
</FluentSelect>
</div>
);
}
export default LocationComboBox;
closing per the above response