1

Imagine a simple React component with <select> element that allows to choose a city based on country. For example

<MyCitySelectComponent
  country={ 'France' }
  city={ 'Paris' }
  onChange={ someFunction }
/>
  • When mounted, it should load list of available Cities (based on Country) and render <select>.
  • When city property is changed - it should modify <select> input value and trigger onChange event.
  • When country property is changed (from parent component) - it should reload list of available cities from a remote server and trigger the same onChange event.

I managed to implement first two, here is simplified code:


class MyCitySelectComponent extends Component {
    constructor(props) {
        super(...props);

        this.state = {
            cities: null,
            city: props.city,
            country: props.country
        };
    }

    onCityChange( e ) {
        this.setState({
            city: e.target.value
        });

        this.props.onChange( e.target.value );
    }

    loadCities() {
        fetch({
            path: '/get/cities?country=' + this.state.country,
        }).then( cities => {
            this.setState({
                cities: cities
            });
        });
    }

    componentDidMount() {
        this.loadCities();
    }

    render() {
        if ( !this.state.cities ) {
            // not loaded yet
            return null;
        }

        return (
            <select>
                { this.state.cities.map( ( name, index ) =>
                    <option
                        value={ name }
                        onChange={ this.onCityChange }
                        selected={ name === this.state.city }
                    />
                ) }
            </select>
        )
    }
}

But I'm having trouble reloading cities when country is changed dynamically from parent component. I tried using shouldComponentUpdate, but all I get is infinite loops.

Is there any pattern for such type of component?

Thank you.

1

1 Answer 1

1

Fetching new data based on prop changes should be handled in componentDidUpdate or getDerivedStateFromProps. Have a look at the docs for an example: https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#fetching-external-data-when-props-change

Note that componentWillReceiveProps is deprecated!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.