Select defaultValue, change or reset: a working example

Hi!
It took me a few hours to understand how this component work, especially when it is about setting a default value or selecting an option dynamically or resetting the component. So for those who will struggle like me, here is an example code that works and could be useful on the documentation page :wink:

https://developer.atlassian.com/platform/forge/ui-kit/components/select/


import React, { useState } from 'react';
import ForgeReconciler, { Text, UserPicker, Textfield, Button, Select } from '@forge/react';

const App = () => {
  const [txt, setTxt] = useState('init');

  const [selectedOption, setSelectedOption] = useState({ label: 'Banana', value: 'b' });
  const [sct, setSct] = useState('b');

  const reset = () => {
    setTxt('');
    setSct('');
    setSelectedOption(null);
  };

  return (
    <>
      <Text>Select: {sct}</Text>
      <Text>Textfield: {txt}</Text>

      <Select
        id="sct"
        name="sct"
        isClearable
        options={[
          { label: 'Apple', value: 'a' },
          { label: 'Banana', value: 'b' },
        ]}
        value={selectedOption}
        onChange={ (v) => {
          if (v === null) { // Click on the clear cross
            setSelectedOption(null);
            setSct('');
          } else if (v.value) {
            setSelectedOption({ label: v.label, value: v.value });
            setSct(v.value);
          }
        }}
      />
      <Textfield
        id="txt"
        name="txt"
        value={txt}
        onChange={ (e) => setTxt(e.target.value) }
      />
      <Button onClick={reset}>Reset</Button>
    </>
  );
};

ForgeReconciler.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

And a version for multiple selection (@YY1 you may be interested by this one :wink: ):

import React, { useState } from 'react';
import ForgeReconciler, { Text, UserPicker, Textfield, Button, Select } from '@forge/react';

const App = () => {
  const [selectedOption, setSelectedOption] = useState({ label: 'Banana', value: 'b' });
  const [sct, setSct] = useState('b');

  const reset = () => {
    setSct('');
    setSelectedOption(null);
  };

  return (
    <>
      <Text>Select: {sct}</Text>

      <Select
        id="sct"
        name="sct"
        isClearable
        isMulti
        options={[
          { label: 'Apple', value: 'a' },
          { label: 'Banana', value: 'b' },
        ]}
        value={selectedOption}
        onChange={ (v) => {
          if (v === null) { // Click on the clear cross
            setSelectedOption(null);
            setSct('');
          } else if (Array.isArray(v)) {
            const options = [];
            const values = [];
            v.forEach((o) => {
              options.push({ label: o.label, value: o.value })
              values.push(o.value);
            })
            setSelectedOption(options);
            setSct(values.join(', '));
          }
        }}
      />
      <Button onClick={reset}>Reset</Button>
    </>
  );
};

ForgeReconciler.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

You may wonder why I do that (publish working examples on that forum) instead of doing my job (developing apps): just because I spent 4 hours doing something that should have been done in 10 minutes. So 5 minutes more to help people, that’s really cheap. I can’t stand to imagine that every Forge developers are in the same situation, much too often.

2 Likes

Hi @BertrandDrouhard1
Thanks so much for your sharing. The solution seems not so easy.
To Atlassian, could we make developers more easily to get things done? @AtlassianSupport
Thanks,
YY

1 Like

Hi @BertrandDrouhard1 ,
Thanks for sharing your findings with the community! To expand on your answer, onChange does not need the additional logic for what you’re trying to do. Here’s an example that replicates the same behaviour you have but removes the logic in onChange. You can reuse the selectOption state for rendering the text above instead. Hope it makes sense!

const SelectExample = () => {
  const [selectedOption, setSelectedOption] = useState([
    {
      label: "Banana",
      value: "b",
    },
  ]);

  const reset = () => {
    setSelectedOption([]);
  };

  return (
    <>
      <Text>
        Select: {selectedOption.map((option) => option.value).join(", ")}
      </Text>

      <Select
        id="sct"
        name="sct"
        isClearable
        isMulti
        options={[
          { label: "Apple", value: "a" },
          { label: "Banana", value: "b" },
        ]}
        value={selectedOption}
        onChange={setSelectedOption}
      />
      <Button onClick={reset}>Reset</Button>
    </>
  );
};

Thank you @QuocLieu , it is definitely simpler. I think the documentation deserves your example!

1 Like

agree