1

I have this wrapper class that is used because I am using Formik and the FieldArray

import React, { Component } from "react";
import { ReactDOM } from "react-dom";
import Select from "react-select";
import { observer } from "mobx-react";
import { axiosInstance } from "../stores/AxiosInstance";

@observer
export default class CountryStateSelectComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { stateOptions: [] };
  }
  handleCountryChange = value => {
    const that = this;

    axiosInstance
      .get(`/States?countryId=${value.value}`)
      .then(function(response) {
        that.props.onChange(that.props.countryName, value);
        that.props.onChange(that.props.stateName, null);

        const states = response.data.map(state => {
          return { label: state.name, value: state.id };
        });
        // if I move out state select code then won't need to update state here but don't know how to call something like updateState(record)
        that.setState({
          stateOptions: states
        });
      });
  };
  handleStateChange = value => {
    console.log(this.props.stateName, value)
    this.props.onChange(this.props.stateName, value);
  };
  handleCountryBlur = () => {
    this.props.onBlur(this.props.countryName, true);
  };
  handleStateBlur = () => {
    this.props.onChange(this.props.stateName, true);
  };
  render() {
    const props = this.props;
    return (
      <React.Fragment>
        <div className="field">
          <label className="label">Country</label>
          <div className="control">
            <Select
              options={props.options}
              isMulti={props.isMulti}
              onChange={this.handleCountryChange}
              onBlur={this.handleCountryBlur}
              closeMenuOnSelect={props.closeMenuOnSelect}
            />
            {this.props.CountryError}
          </div>
        </div>

        <div className="field">
          <label className="label">State/Province</label>
          <div className="control">
            <Select
              options={this.state.stateOptions}     
              onChange={this.handleStateChange}
              onBlur={this.handleStateBlur}
            />
            {this.props.StateError}
          </div>
        </div>
      </React.Fragment>
    );
  }
}

However what I found is that when the State gets selected the value does not get stored in Formik(it gets stored as undefined and sometimes true).

So now I am thinking maybe moving out the State Zip out and making it's own wrapper or something but I don't know how to get the "states" that came back and populate the correct state box as they can generate many.

@inject("AccountSetupStore")
@observer
export default class MyComponent extends Component {
  constructor(props) {
    super(props);
    this.state = { records:  [this.generateRecord(1, true, true)] };
  }
  componentDidMount() {
    const accountSetupStore = this.props.AccountSetupStore;
    accountSetupStore.getCountries();
  }
  updateState(record) {
      // would like to call this method that can somehow update the record
      // propblem is I don't seem to have access to props when this function is being called from the CountryStateSelectComponent
  }
  render() {
    const props = this.props;
    const accountSetupStore = props.AccountSetupStore;

    const countries = [];
    for (const country of accountSetupStore.countries) {
      countries.push({ value: country.id, label: country.name });
    }


    return (
      <section className="accordions">
        <Formik
          initialValues={{
            records: this.state.records
          }}
          onSubmit={(
            values,
            { setSubmitting, setErrors}
          ) => {

            console.log(values,"values");
          }}
          validationSchema={Yup.object().shape({
            branches: Yup.array()
              .of(
                Yup.object().shape({
                })
              )
          })}
          render={({
            values,
            setFieldValue,
            setFieldTouched,
          }) => (
            <FieldArray
              name="records"
              render={arrayHelpers => (
                <Form>
                  {values.records.map((record, index) => {
                     return (<article}>
                       <CountryStateSelectComponent options={countries} 
                                onChange={setFieldValue}
                                countryName={`records[${index}].selectedCountry`}
                                stateName={`records[0].selectedState`}
                                onBlur={setFieldTouched}
                                isMulti={false}
                                index = {index}
                                closeMenuOnSelect={true}
                                CountryError = {<ErrorMessage name={`records[${index}].selectedCountry`}/>}
                                StateError= {<ErrorMessage name={`records[${index}].selectedState`}/>}
                            />
                   </article>)
                  })}
                </Form>
              )}
            />
          )}
        />
      </section>
    );
  }
}
2
  • You should have ids set for each instance if you’re using more than one select at a time Commented Jun 21, 2018 at 21:27
  • why? I am not referring to any id. Can you explain in more detail. Commented Jun 21, 2018 at 21:48

1 Answer 1

1

React Select onChange sends the value to the method supplied

const onStateChange = (selectedOption, {action}) => {
  //do something with the selectedOption according to the action
}

<Select onChange={onStateChange} />

See the documentation for the onChange in the Props documentation.

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.