<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Fluent UI on Andrew Wilson's Blog</title><link>https://andrewilson.co.uk/tags/fluent-ui/</link><description>Recent content in Fluent UI on Andrew Wilson's Blog</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Mon, 13 Feb 2023 00:00:00 +0000</lastBuildDate><atom:link href="https://andrewilson.co.uk/tags/fluent-ui/index.xml" rel="self" type="application/rss+xml"/><item><title>Fluent UI | React | Controlled multi-select Dropdown - Selected Keys</title><link>https://andrewilson.co.uk/post/2023/02/fluent-ui-react-controlled-multi-select-dropdown-selected-keys/</link><pubDate>Mon, 13 Feb 2023 00:00:00 +0000</pubDate><guid>https://andrewilson.co.uk/post/2023/02/fluent-ui-react-controlled-multi-select-dropdown-selected-keys/</guid><description>&lt;h2 id="problem-space"&gt;Problem Space&lt;/h2&gt;
&lt;p&gt;I ran into a problem the other day working with the Fluent UI React component &lt;code&gt;Controlled Multi-select Dropdown&lt;/code&gt;. As context, here is my redacted code and explanation:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;import&lt;/span&gt; { Dropdown, IDropdownOption } &lt;span style="color:#ff79c6"&gt;from&lt;/span&gt; &lt;span style="color:#f1fa8c"&gt;&amp;#39;office-ui-fabric-react&amp;#39;&lt;/span&gt;; &lt;span style="color:#6272a4"&gt;// office-ui-fabric-react@7.204.0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;export&lt;/span&gt; &lt;span style="color:#ff79c6"&gt;interface&lt;/span&gt; State {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; itemList: &lt;span style="color:#8be9fd"&gt;IDropdownOption&lt;/span&gt;[];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; selectedItems: &lt;span style="color:#8be9fd"&gt;string&lt;/span&gt;[];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;export&lt;/span&gt; &lt;span style="color:#ff79c6"&gt;default&lt;/span&gt; &lt;span style="color:#ff79c6"&gt;class&lt;/span&gt; DropDownExample &lt;span style="color:#ff79c6"&gt;extends&lt;/span&gt; React.Component&amp;lt;&lt;span style="color:#ff79c6"&gt;any&lt;/span&gt;, &lt;span style="color:#50fa7b"&gt;State&lt;/span&gt;&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ff79c6"&gt;constructor&lt;/span&gt;(context) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ff79c6"&gt;super&lt;/span&gt;(context);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ff79c6"&gt;this&lt;/span&gt;.state &lt;span style="color:#ff79c6"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; itemList&lt;span style="color:#ff79c6"&gt;:&lt;/span&gt; [{ key&lt;span style="color:#ff79c6"&gt;:&lt;/span&gt; &lt;span style="color:#f1fa8c"&gt;&amp;#39;None&amp;#39;&lt;/span&gt;, text&lt;span style="color:#ff79c6"&gt;:&lt;/span&gt; &lt;span style="color:#f1fa8c"&gt;&amp;#39;None&amp;#39;&lt;/span&gt; }],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; selectedItems&lt;span style="color:#ff79c6"&gt;:&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ff79c6"&gt;this&lt;/span&gt;.GetItems();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ff79c6"&gt;this&lt;/span&gt;.LoadPreselection();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ff79c6"&gt;private&lt;/span&gt; &lt;span style="color:#ff79c6"&gt;async&lt;/span&gt; GetItems(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#6272a4"&gt;// ... load items into itemList
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ff79c6"&gt;private&lt;/span&gt; &lt;span style="color:#ff79c6"&gt;async&lt;/span&gt; LoadPreselection(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#6272a4"&gt;// ... load pre-selected items into selectedItems
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ff79c6"&gt;public&lt;/span&gt; onItemChange &lt;span style="color:#ff79c6"&gt;=&lt;/span&gt; (event: &lt;span style="color:#8be9fd"&gt;React.FormEvent&lt;/span&gt;&amp;lt;&lt;span style="color:#ff79c6"&gt;HTMLDivElement&lt;/span&gt;&amp;gt;, item: &lt;span style="color:#8be9fd"&gt;IDropdownOption&lt;/span&gt;)&lt;span style="color:#ff79c6"&gt;:&lt;/span&gt; &lt;span style="color:#ff79c6"&gt;void&lt;/span&gt; &lt;span style="color:#ff79c6"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ff79c6"&gt;if&lt;/span&gt; (item) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#8be9fd;font-style:italic"&gt;let&lt;/span&gt; tempItemsArray &lt;span style="color:#ff79c6"&gt;=&lt;/span&gt; selectedKeys;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ff79c6"&gt;const&lt;/span&gt; index &lt;span style="color:#ff79c6"&gt;=&lt;/span&gt; tempItemsArray.indexOf(item.key, &lt;span style="color:#bd93f9"&gt;0&lt;/span&gt;); &lt;span style="color:#6272a4"&gt;// Obtain item index if exists - returns -1 if it does not
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ff79c6"&gt;if&lt;/span&gt; (index &lt;span style="color:#ff79c6"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#ff79c6"&gt;-&lt;/span&gt;&lt;span style="color:#bd93f9"&gt;1&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tempItemsArray.splice(index, &lt;span style="color:#bd93f9"&gt;1&lt;/span&gt;); &lt;span style="color:#6272a4"&gt;// If the item exists, remove the item from the existing array through the splice function
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#ff79c6"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tempItemsArray.push(item.key); &lt;span style="color:#6272a4"&gt;// If the item does not exist, add the item to the existing array
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; setSelectedKeys(tempItemsArray); &lt;span style="color:#6272a4"&gt;// Update State
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; render() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ff79c6"&gt;return&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#ff79c6"&gt;Dropdown&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#50fa7b"&gt;placeholder&lt;/span&gt;&lt;span style="color:#ff79c6"&gt;=&lt;/span&gt;&lt;span style="color:#f1fa8c"&gt;&amp;#34;[Select Item]&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#50fa7b"&gt;disabled&lt;/span&gt;&lt;span style="color:#ff79c6"&gt;=&lt;/span&gt;{&lt;span style="color:#ff79c6"&gt;this&lt;/span&gt;.state.itemList.length &lt;span style="color:#ff79c6"&gt;===&lt;/span&gt; &lt;span style="color:#bd93f9"&gt;0&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#50fa7b"&gt;label&lt;/span&gt;&lt;span style="color:#ff79c6"&gt;=&lt;/span&gt;&lt;span style="color:#f1fa8c"&gt;&amp;#39;Items&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#50fa7b"&gt;id&lt;/span&gt;&lt;span style="color:#ff79c6"&gt;=&lt;/span&gt;&lt;span style="color:#f1fa8c"&gt;&amp;#39;items&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#50fa7b"&gt;responsiveMode&lt;/span&gt;&lt;span style="color:#ff79c6"&gt;=&lt;/span&gt;{&lt;span style="color:#bd93f9"&gt;1&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#50fa7b"&gt;multiSelect&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#50fa7b"&gt;options&lt;/span&gt;&lt;span style="color:#ff79c6"&gt;=&lt;/span&gt;{&lt;span style="color:#ff79c6"&gt;this&lt;/span&gt;.state.itemList}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#50fa7b"&gt;selectedKeys&lt;/span&gt;&lt;span style="color:#ff79c6"&gt;=&lt;/span&gt;{&lt;span style="color:#ff79c6"&gt;this&lt;/span&gt;.state.selectedItems}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#50fa7b"&gt;onChange&lt;/span&gt;&lt;span style="color:#ff79c6"&gt;=&lt;/span&gt;{&lt;span style="color:#ff79c6"&gt;this&lt;/span&gt;.onItemChange.bind(&lt;span style="color:#ff79c6"&gt;this&lt;/span&gt;)}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; );
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I had a list of items that I wanted to load into the Multi-select control from an API call. After obtaining the list of items, I wanted to preload any previously selected items.&lt;/p&gt;</description><content:encoded><![CDATA[<h2 id="problem-space">Problem Space</h2>
<p>I ran into a problem the other day working with the Fluent UI React component <code>Controlled Multi-select Dropdown</code>. As context, here is my redacted code and explanation:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">import</span> { Dropdown, IDropdownOption } <span style="color:#ff79c6">from</span> <span style="color:#f1fa8c">&#39;office-ui-fabric-react&#39;</span>; <span style="color:#6272a4">// office-ui-fabric-react@7.204.0
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">export</span> <span style="color:#ff79c6">interface</span> State {
</span></span><span style="display:flex;"><span>	itemList: <span style="color:#8be9fd">IDropdownOption</span>[];
</span></span><span style="display:flex;"><span>	selectedItems: <span style="color:#8be9fd">string</span>[];
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">export</span> <span style="color:#ff79c6">default</span> <span style="color:#ff79c6">class</span> DropDownExample <span style="color:#ff79c6">extends</span> React.Component&lt;<span style="color:#ff79c6">any</span>, <span style="color:#50fa7b">State</span>&gt; {
</span></span><span style="display:flex;"><span>	<span style="color:#ff79c6">constructor</span>(context) {
</span></span><span style="display:flex;"><span>		<span style="color:#ff79c6">super</span>(context);
</span></span><span style="display:flex;"><span>		<span style="color:#ff79c6">this</span>.state <span style="color:#ff79c6">=</span> {
</span></span><span style="display:flex;"><span>			itemList<span style="color:#ff79c6">:</span> [{ key<span style="color:#ff79c6">:</span> <span style="color:#f1fa8c">&#39;None&#39;</span>, text<span style="color:#ff79c6">:</span> <span style="color:#f1fa8c">&#39;None&#39;</span> }],
</span></span><span style="display:flex;"><span>			selectedItems<span style="color:#ff79c6">:</span> []
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>		<span style="color:#ff79c6">this</span>.GetItems();
</span></span><span style="display:flex;"><span>		<span style="color:#ff79c6">this</span>.LoadPreselection();
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>		
</span></span><span style="display:flex;"><span>	<span style="color:#ff79c6">private</span> <span style="color:#ff79c6">async</span> GetItems(){
</span></span><span style="display:flex;"><span>		<span style="color:#6272a4">// ... load items into itemList
</span></span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#ff79c6">private</span> <span style="color:#ff79c6">async</span> LoadPreselection(){
</span></span><span style="display:flex;"><span>		<span style="color:#6272a4">// ... load pre-selected items into selectedItems
</span></span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#ff79c6">public</span> onItemChange <span style="color:#ff79c6">=</span> (event: <span style="color:#8be9fd">React.FormEvent</span>&lt;<span style="color:#ff79c6">HTMLDivElement</span>&gt;, item: <span style="color:#8be9fd">IDropdownOption</span>)<span style="color:#ff79c6">:</span> <span style="color:#ff79c6">void</span> <span style="color:#ff79c6">=&gt;</span> {
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>		<span style="color:#ff79c6">if</span> (item) {
</span></span><span style="display:flex;"><span>      		<span style="color:#8be9fd;font-style:italic">let</span> tempItemsArray <span style="color:#ff79c6">=</span> selectedKeys;
</span></span><span style="display:flex;"><span>      		<span style="color:#ff79c6">const</span> index <span style="color:#ff79c6">=</span> tempItemsArray.indexOf(item.key, <span style="color:#bd93f9">0</span>); <span style="color:#6272a4">// Obtain item index if exists - returns -1 if it does not
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      		<span style="color:#ff79c6">if</span> (index <span style="color:#ff79c6">&gt;</span> <span style="color:#ff79c6">-</span><span style="color:#bd93f9">1</span>) {
</span></span><span style="display:flex;"><span>      		   tempItemsArray.splice(index, <span style="color:#bd93f9">1</span>); <span style="color:#6272a4">// If the item exists, remove the item from the existing array through the splice function
</span></span></span><span style="display:flex;"><span>			} <span style="color:#ff79c6">else</span> {
</span></span><span style="display:flex;"><span>      		  tempItemsArray.push(item.key); <span style="color:#6272a4">// If the item does not exist, add the item to the existing array
</span></span></span><span style="display:flex;"><span>      		}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      		setSelectedKeys(tempItemsArray); <span style="color:#6272a4">// Update State
</span></span></span><span style="display:flex;"><span>    	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	render() {
</span></span><span style="display:flex;"><span>		<span style="color:#ff79c6">return</span> (
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>			...
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>			&lt;<span style="color:#ff79c6">Dropdown</span>
</span></span><span style="display:flex;"><span>				<span style="color:#50fa7b">placeholder</span><span style="color:#ff79c6">=</span><span style="color:#f1fa8c">&#34;[Select Item]&#34;</span>
</span></span><span style="display:flex;"><span>				<span style="color:#50fa7b">disabled</span><span style="color:#ff79c6">=</span>{<span style="color:#ff79c6">this</span>.state.itemList.length <span style="color:#ff79c6">===</span> <span style="color:#bd93f9">0</span>}
</span></span><span style="display:flex;"><span>				<span style="color:#50fa7b">label</span><span style="color:#ff79c6">=</span><span style="color:#f1fa8c">&#39;Items&#39;</span>
</span></span><span style="display:flex;"><span>				<span style="color:#50fa7b">id</span><span style="color:#ff79c6">=</span><span style="color:#f1fa8c">&#39;items&#39;</span>
</span></span><span style="display:flex;"><span>				<span style="color:#50fa7b">responsiveMode</span><span style="color:#ff79c6">=</span>{<span style="color:#bd93f9">1</span>}
</span></span><span style="display:flex;"><span>				<span style="color:#50fa7b">multiSelect</span>
</span></span><span style="display:flex;"><span>				<span style="color:#50fa7b">options</span><span style="color:#ff79c6">=</span>{<span style="color:#ff79c6">this</span>.state.itemList}
</span></span><span style="display:flex;"><span>				<span style="color:#50fa7b">selectedKeys</span><span style="color:#ff79c6">=</span>{<span style="color:#ff79c6">this</span>.state.selectedItems}
</span></span><span style="display:flex;"><span>				<span style="color:#50fa7b">onChange</span><span style="color:#ff79c6">=</span>{<span style="color:#ff79c6">this</span>.onItemChange.bind(<span style="color:#ff79c6">this</span>)}
</span></span><span style="display:flex;"><span>			/&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>			...
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>		);
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>I had a list of items that I wanted to load into the Multi-select control from an API call. After obtaining the list of items, I wanted to preload any previously selected items.</p>
<p>At this point there were no problems&hellip;. until I had written my <code>onchange</code> method. For some reason I was able to manage the list of selected keys absolutely fine, but there were no visible changes to the UI selection when clicking.</p>
<p>For example:</p>
<ol>
<li>Open drop down.</li>
<li>Select an option.
<ul>
<li>onChange event triggered (state managed).</li>
<li>Selection in dropdown hasn&rsquo;t changed (Item UI does not confirm selection OR un-selection)</li>
</ul>
</li>
</ol>
<p>As you can imagine, this caused some confusion. The SelectedKeys Array has the correct values but the control is not confirming what I am seeing behind the scenes.</p>
<p>This is until the penny dropped when reviewing example solutions.</p>
<h2 id="solution">Solution</h2>
<p>The Dropdown control is treating the selectedKeys as an IMutable <em><code>&quot;(Once set, it cannot be changed)&quot;</code></em>. This completely changes the onChanged method solution.</p>
<p>Rather than <code>Push</code> to the <code>existing</code> array, we need to use the <code>Spread</code> syntax. The spread syntax will add the new item along with the already existing items into a <code>new array</code> that can be used by the control. Such as:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>...<span style="color:#ff79c6">this</span>.state.selectedItems, item.key <span style="color:#ff79c6">as</span> <span style="color:#8be9fd">string</span>
</span></span></code></pre></div><p>Rather than using <code>Splice</code> to remove an element from an <code>existing</code> array, we need to use the <code>Filter</code> method. The filter method creates a <code>new</code> array with all the elements that pass the logic test supplied, in this case bring everything over that doesn&rsquo;t match the selected item. Such as:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">this</span>.state.selectedItems.filter(key <span style="color:#ff79c6">=&gt;</span> key <span style="color:#ff79c6">!==</span> item.key)
</span></span></code></pre></div><p>Combined, my <code>onChange</code> method now takes on the following form and operates as expected:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">public</span> onItemChange <span style="color:#ff79c6">=</span> (event: <span style="color:#8be9fd">React.FormEvent</span>&lt;<span style="color:#ff79c6">HTMLDivElement</span>&gt;, item: <span style="color:#8be9fd">IDropdownOption</span>)<span style="color:#ff79c6">:</span> <span style="color:#ff79c6">void</span> <span style="color:#ff79c6">=&gt;</span> {
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>		<span style="color:#ff79c6">if</span> (item) {
</span></span><span style="display:flex;"><span>			<span style="color:#ff79c6">this</span>.setState({
</span></span><span style="display:flex;"><span>				selectedItems:
</span></span><span style="display:flex;"><span>					<span style="color:#8be9fd">item.selected</span>
</span></span><span style="display:flex;"><span>						<span style="color:#ff79c6">?</span> [...<span style="color:#ff79c6">this</span>.state.selectedItems, item.key <span style="color:#ff79c6">as</span> <span style="color:#8be9fd">string</span>]
</span></span><span style="display:flex;"><span>						<span style="color:#ff79c6">:</span> <span style="color:#ff79c6">this</span>.state.selectedItems.filter(key <span style="color:#ff79c6">=&gt;</span> key <span style="color:#ff79c6">!==</span> item.key),
</span></span><span style="display:flex;"><span>			});
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	}
</span></span></code></pre></div>]]></content:encoded></item></channel></rss>