country-state-city-react
v1.0.1
Published
A React package for accessing hierarchical country, state, and city data with reusable components and hooks
Maintainers
Readme
React Country State City
A lightweight, flexible React package for handling hierarchical country, state, and city data with reusable components and hooks.
Features
- 🌍 Hierarchical location data (Countries → States → Cities)
- 🎣 Custom React hooks for data management
- 🧩 Ready-to-use dropdown selector component
- 📦 TypeScript support with full type definitions
- 🚀 Optimized performance with minimal bundle size
- 🎨 Customizable styling with CSS classes
- 🔍 Search functionality for all location levels
Installation
npm install country-state-city-reactyarn add country-state-city-reactQuick Start
Basic Component Usage
import React from 'react';
import { CountryStateCitySelector } from 'country-state-city-react';
function App() {
const handleLocationChange = (country, state, city) => {
console.log('Selected:', { country, state, city });
};
return (
<CountryStateCitySelector
onCountryChange={(country) => handleLocationChange(country, null, null)}
onStateChange={(state) => handleLocationChange(null, state, null)}
onCityChange={(city) => handleLocationChange(null, null, city)}
/>
);
}
export default App;Using Utility Functions
import React, { useState, useEffect } from 'react';
import { getCountries, getStatesByCountry, getCitiesByState } from 'country-state-city-react';
function CustomSelector() {
const [countries] = useState(getCountries());
const [states, setStates] = useState([]);
const [cities, setCities] = useState([]);
const [selectedCountry, setSelectedCountry] = useState('');
useEffect(() => {
if (selectedCountry) {
setStates(getStatesByCountry(selectedCountry));
}
}, [selectedCountry]);
return (
<div>
<select onChange={(e) => setSelectedCountry(e.target.value)}>
<option value="">Select Country</option>
{countries.map((country) => (
<option key={country.code} value={country.code}>
{country.name}
</option>
))}
</select>
{/* Add state and city selectors */}
</div>
);
}Using Hooks
import React from 'react';
import { useLocationSelector } from 'country-state-city-react';
function HookExample() {
const {
countries,
states,
cities,
selectedCountry,
selectedState,
selectedCity,
setSelectedCountry,
setSelectedState,
setSelectedCity
} = useLocationSelector();
return (
<div>
<h3>Selected Location:</h3>
<p>Country: {selectedCountry?.name || 'None'}</p>
<p>State: {selectedState?.name || 'None'}</p>
<p>City: {selectedCity?.name || 'None'}</p>
</div>
);
}API Reference
Components
CountryStateCitySelector
A complete dropdown selector component with linked country, state, and city selection.
Props:
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| onCountryChange | (country: Country \| null) => void | - | Callback when country changes |
| onStateChange | (state: State \| null) => void | - | Callback when state changes |
| onCityChange | (city: City \| null) => void | - | Callback when city changes |
| defaultCountry | string | - | Default country code |
| defaultState | string | - | Default state code |
| defaultCity | string | - | Default city ID |
| className | string | '' | CSS class for container |
| countryClassName | string | '' | CSS class for country select |
| stateClassName | string | '' | CSS class for state select |
| cityClassName | string | '' | CSS class for city select |
| countryPlaceholder | string | 'Select Country' | Country dropdown placeholder |
| statePlaceholder | string | 'Select State' | State dropdown placeholder |
| cityPlaceholder | string | 'Select City' | City dropdown placeholder |
| disabled | boolean | false | Disable all dropdowns |
Utility Functions
getCountries(): Country[]
Returns all available countries.
getStatesByCountry(countryCode: string): State[]
Returns states for a specific country.
getCitiesByState(countryCode: string, stateCode: string): City[]
Returns cities for a specific state in a country.
getCountryByCode(countryCode: string): Country | null
Returns a country object by its code.
getStateByCode(countryCode: string, stateCode: string): State | null
Returns a state object by country and state codes.
getCityById(countryCode: string, stateCode: string, cityId: string): City | null
Returns a city object by country code, state code, and city ID.
Search Functions
searchCountries(query: string): Country[]- Search countries by namesearchStates(countryCode: string, query: string): State[]- Search states within a countrysearchCities(countryCode: string, stateCode: string, query: string): City[]- Search cities within a state
Hooks
useCountries(): Country[]
Returns all countries. Data is memoized for performance.
useStates(countryCode: string | null): State[]
Returns states for the selected country. Updates automatically when country changes.
useCities(countryCode: string | null, stateCode: string | null): City[]
Returns cities for the selected state. Updates automatically when country or state changes.
useLocationSelector(defaultCountry?, defaultState?, defaultCity?)
Complete hook for managing the entire selection flow.
Returns:
{
countries: Country[];
states: State[];
cities: City[];
selectedCountry: Country | null;
selectedState: State | null;
selectedCity: City | null;
setSelectedCountry: (country: Country | null) => void;
setSelectedState: (state: State | null) => void;
setSelectedCity: (city: City | null) => void;
}Type Definitions
interface Country {
code: string;
name: string;
states: State[];
}
interface State {
code: string;
name: string;
cities: City[];
}
interface City {
id: string;
name: string;
}Advanced Usage
Custom Styling
import { CountryStateCitySelector } from 'country-state-city-react';
function StyledSelector() {
return (
<CountryStateCitySelector
className="max-w-md mx-auto"
countryClassName="border-2 border-blue-500 rounded-lg"
stateClassName="border-2 border-green-500 rounded-lg"
cityClassName="border-2 border-purple-500 rounded-lg"
countryPlaceholder="Choose your country"
statePlaceholder="Choose your state"
cityPlaceholder="Choose your city"
/>
);
}With Default Values
function PreselectedSelector() {
return (
<CountryStateCitySelector
defaultCountry="US"
defaultState="CA"
defaultCity="1"
onCountryChange={(country) => console.log('Country:', country)}
onStateChange={(state) => console.log('State:', state)}
onCityChange={(city) => console.log('City:', city)}
/>
);
}Search Implementation
import React, { useState } from 'react';
import { searchCountries, searchStates, searchCities } from 'country-state-city-react';
function SearchExample() {
const [countryQuery, setCountryQuery] = useState('');
const [results, setResults] = useState([]);
const handleSearch = (query) => {
setCountryQuery(query);
if (query.length > 1) {
setResults(searchCountries(query));
} else {
setResults([]);
}
};
return (
<div>
<input
type="text"
placeholder="Search countries..."
value={countryQuery}
onChange={(e) => handleSearch(e.target.value)}
/>
<ul>
{results.map((country) => (
<li key={country.code}>{country.name}</li>
))}
</ul>
</div>
);
}Form Integration
import React from 'react';
import { useForm } from 'react-hook-form';
import { CountryStateCitySelector } from 'country-state-city-react';
function FormExample() {
const { register, handleSubmit, setValue, watch } = useForm();
const onSubmit = (data) => {
console.log('Form data:', data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<CountryStateCitySelector
onCountryChange={(country) => setValue('country', country?.code)}
onStateChange={(state) => setValue('state', state?.code)}
onCityChange={(city) => setValue('city', city?.id)}
/>
<button type="submit">Submit</button>
</form>
);
}Data Structure
The package includes sample data for:
- United States: California, New York, Texas, Florida (with 4 cities each)
- Canada: Ontario, British Columbia, Quebec (with 4 cities each)
- United Kingdom: England, Scotland, Wales (with 4 cities each)
- India: Maharashtra, Karnataka, Delhi (with 4 cities each)
Extending Data
To use your own data, you can import the utility functions and provide your own data source:
// custom-data.ts
import { Country } from 'country-state-city-react';
export const customCountries: Country[] = [
{
code: 'CUSTOM',
name: 'Custom Country',
states: [
{
code: 'CS1',
name: 'Custom State 1',
cities: [
{ id: '1', name: 'Custom City 1' },
{ id: '2', name: 'Custom City 2' }
]
}
]
}
];Performance Considerations
- Data is loaded synchronously from a bundled JSON file
- All hooks use React's built-in memoization
- Component re-renders are optimized with proper dependency arrays
- Total bundle size is minimal (~15KB gzipped)
Browser Support
- Modern browsers (ES2015+)
- React 16.8+ (hooks support required)
- TypeScript 4.0+ (if using TypeScript)
Contributing
We welcome contributions! Please follow these steps:
Fork the repository
git clone https://github.com/your-username/country-state-city-react.git cd country-state-city-reactInstall dependencies
npm installMake your changes
- Add new features or fix bugs
- Update tests if necessary
- Update documentation
Build and test
npm run build npm testSubmit a Pull Request
- Describe your changes clearly
- Include any breaking changes in the description
- Add tests for new functionality
Development Scripts
npm run dev # Start development build with watch mode
npm run build # Build for production
npm run test # Run tests
npm run lint # Run lintingAdding New Data
To add new countries, states, or cities:
- Edit
src/data/locations.json - Follow the existing data structure
- Ensure all entries have unique codes/IDs
- Test thoroughly with the provided components
Code Style
- Use TypeScript for all new code
- Follow existing naming conventions
- Add JSDoc comments for public APIs
- Use meaningful variable and function names
Changelog
v1.0.0
- Initial release
- Basic country, state, city selection
- TypeScript support
- React hooks integration
- Search functionality
- Customizable styling
License
MIT License - see LICENSE file for details.
Support
Related Packages
- react-select - For advanced dropdown functionality
- react-hook-form - For form integration
- world-countries - For comprehensive country data
Made with ❤️ by the React Community
