How to load a listbox of states depending on the selected country in RemixRun?

Viewed 43

I love Remix, but there are some things I wonder how it could be achieved.

Let say I have 2 listboxes, one for the country and a second for the state.

How would I achieve the loading of the states depending on the country selection from the previous list?

1 Answers

Here's a quick demo. I'm using useFetcher to load data when country changes. As you can see I also sent the initial data from the loader.

export const loader: LoaderFunction = async ({ request }) => {
  const url = new URL(request.url)
  const country = url.searchParams.get('country') || 'United States'
  const countries = Object.keys(statesByCountry)
  const states = statesByCountry[country]

  return json({ countries, country, states })
}

export default function Index() {
  const initialData = useLoaderData()
  const fetcher = useFetcher()
  const { countries, country, states } = fetcher.data ?? initialData

  const handleChange = (e) => {
    const params = new URLSearchParams()
    params.set('country', e.target.value)
    fetcher.load(`?index&${params.toString()}`)
  }
  return (
    <div className="m-2">
      <h1 className="text-2xl font-bold">Remix Dual Lists!</h1>
      <div className="flex gap-4">
        <select
          name="country"
          defaultValue={country}
          onChange={handleChange}
          size={10}
        >
          {countries.map((country) => (
            <option>{country}</option>
          ))}
        </select>
        <select name="state" size={10}>
          {states.map((state) => (
            <option>{state}</option>
          ))}
        </select>
      </div>
    </div>
  )
}

https://codesandbox.io/s/remix-dual-lists-epcxvu?file=/app/routes/index.tsx

Related