0

Hopefully someone can point me in the right direction to the cleanest/most accepted way of storing HTML markup in React apps.

Imagine my scenario: I have a country dropdown menu (<select>). When you select a country from the menu, a "State/Province" <select> becomes visible. Based on the country you picked, a React.Fragment is inserted into the new "State/Province" <select> field giving you options for the country you've selected.

Everything works fine; problem is I have three very large React.Fragments as variables/members in my component class above all my methods. One of them looks like this.

canadaStateProvinceOptions = (
    <React.Fragment>
        <option value="">--Choose One--</option>
        <option value="AB">Alberta</option>
        <option value="BC">British Columbia</option>
        <option value="CD">Canada (Province unknown)</option>
        <option value="MB">Manitoba</option>
        <option value="XN">Nunavut Providence</option>
        <option value="NF">Newfoundland (Includes Labrador)</option>
        <option value="NK">New Brunswick</option>
        <option value="NS">Nova Scotia</option>
        <option value="NT">Northwest Territories (Canadian Admin. Division)</option>
        <option value="ON">Ontario</option>
        <option value="PE">Prince Edward Island</option>
        <option value="PQ">Quebec</option>
        <option value="SN">Saskatchewan</option>
        <option value="YT">Yukon (Canadian Territory)</option>
    </React.Fragment>
);

There are two more which have way more options.. Should I be keeping these as class members of my component or is there a better way to separate this concern?

  • 2
    React is data driven, you could store the country codes and names in static JSON file and just write a small JSX loop to render the options. – Emile Bergeron Dec 09 '19 at 23:52
  • 1
    @EmileBergeron The answer on that link you posted is very interesting and clean. I like the approach. Thank you for your patience in my being new to React. My next best idea was to make this page of the form I'm building into it's own component nested into the main form.. I felt like I had way too much dead markup! –  Dec 09 '19 at 23:56

2 Answers2

2

Instead of storing entire fragments, save just the data you need and then iterate through them. So your example would look something like

const canadianProvinceOptions = [
  {
    value: 'AB',
    name: 'Alberta',
  },
  {
    value: 'BC',
    name: 'British Columbia',
  }
  ...etc
]

And then when you need to use them, you can do something like

<select ...>
  <option value="">--Choose One--</option>
  {canadianProvinceOptions.map(option => (
    <option value={option.value}>{option.name}</option>
  ))}
</select>
larz
  • 5,724
  • 2
  • 11
  • 20
1

Define the options as an array. You can do this in a seperate file

const canadaStateProvinceOptions = [
    {value: "", label: "--Choose One--"},
    {value: "AB", label: "Alberta"},
    // add more values here
]

This is your main App component or the parent component

const MyAppComponent = () => (
    <div>
        <p> Random stuff </p>
        <p> The select </p>
        <ComponentWithOptions options={canadaStateProvinceOptions} />
    </div>
)

A simple util component that removes the boilerplate Fragment,option hell

const ComponentWithOptions = ({options}) => (
    <React.Fragment>
        {options.map({value, label} => <option value={value}>{label}</option>)}
    </React.Fragment>
)
ssbarbee
  • 1,626
  • 2
  • 16
  • 24