Ошибка выбора на основе выбора из 1-го выбора в реактивных крючках и динамических входах

#reactjs #react-hooks

#reactjs #реагирующие перехватчики

Вопрос:

У меня есть два выбора, и я хочу заполнить вторую базу выбора при выборе первого в react. Когда я выбираю страну, я хочу, чтобы отображался select2 с его состояниями, а значение во втором выборе обновлялось с выбранным значением.

У меня есть следующий код,

 const MyForm = (props) => {    
    const COUNTRIES = [
        {
            displayValue: "Country1",
            value: "C1"
        },
        {
            displayValue: "Country2",
            value: "C2"
        }
    ]        
    const STATES = {
        "": [ {
            displayValue: "",
            value: ""
        }],
        "C1": [{
            displayValue: "State 1",
            value: "S11"
        },
        {
            displayValue: "State 2",
            value: "S12"
        }],
        "C2": [{
            displayValue: "State n1",
            value: "C21"
        },
        {
            displayValue: "STate n2",
            value: "C22"
        }]
    }    
    let inputsForms = {
      country: {
          elementType: 'select',
          elementConfig: {
              type: 'select',
              placeholder: '',
              options: COUNTRIES,
              firstOption: "-- Choose Country"
          },
          value: ''
      },
      states: {
        elementType: 'select',
        elementConfig: {
            type: 'select',
            placeholder: '',
            options: [], // I need these options depend on the countrie selected  STATES["C1"]
            firstOption: "-- Choose States"
        },
        value: ''
    }      
  }
        
  const [myForm, setmyForm] = useState(inputsForms);

  const updateObject = (oldObject, updatedProperties) => {
        return {
            ...oldObject,
            ...updatedProperties
        };
    };  
  
  const inputChangedHandler = (e, controlName) => {
    const countrieValue = controlName ==="country"?e.target.value:"";
    const stateOptions = myForm["states"].elementConfig;
    stateOptions["options"] = STATES[countrieValue];

      const updatedControls = updateObject(myForm, {
          [controlName]: updateObject(myForm[controlName], {
            value: e.target.value
          })
        });

        setmyForm(updatedControls);

  }


  const ElementsArray = [];
  for (let key in myForm) {
      ElementsArray.push({
          id: key,
          config: myForm[key]
      });
  }

  let form = (
      <form>
          {ElementsArray.map(el => (
              <Input 
              key={el.id}
              elementType={el.config.elementType}
              elementConfig={el.config.elementConfig}
              value={el.config.value}              
              changed={e => inputChangedHandler(e, el.id)}
              firstOption={el.config.firstOption}
          />
              ))}
          
      </form>
      
          );

  return(
        <div>
            {form}
        </div>
  );
}

export default MyForm;
 

Параметры зависят от выбора 2, однако, когда я выбираю параметр при втором выборе, параметры исчезают, а значение выбора 2 не обновляется.

Спасибо.

Ответ №1:

Поскольку inputChangeHandler вызывается при каждом изменении ввода, данные сбрасываются даже при изменении состояния. Вы можете проверить значение contrieValue и установить данные состояния, чтобы данные не сбрасывались.

 const inputChangedHandler = (e, controlName) => {
  const countrieValue = controlName === "country" ? e.target.value : "";
  if (countrieValue) {
    const stateOptions = myForm["states"].elementConfig;
    stateOptions["options"] = STATES[countrieValue];

    const updatedControls = updateObject(myForm, {
      [controlName]: updateObject(myForm[controlName], {
        value: e.target.value
      })
    });

    setmyForm(updatedControls);

  }
} 

Комментарии:

1. Спасибо за ваш ответ. Вы правы в отношении причины ошибки, что вы предлагаете для ее исправления? Я попробовал с if (countrrievalue), и это не сработало.

Ответ №2:

Вам нужно добавить своего рода условие для обновления состояния всякий раз, когда выбирается состояние, чтобы оно не влияло на исходный объект country.

 const inputChangedHandler = (e, controlName) => {
  if (countrolName === 'states') {
    // your logic here
    return;
  }

  const countrieValue = controlName === 'country' ? e.target.value : '';
  const stateOptions = myForm['states'].elementConfig;
  stateOptions['options'] = STATES[countrieValue];

  const updatedControls = updateObject(myForm, {
    [controlName]: updateObject(myForm[controlName], {
      value: e.target.value,
    }),
  });

  setmyForm(updatedControls);
};
 

Комментарии:

1. да, вы правы, но я до сих пор не знаю, какой будет логика.

2. Вам нужно значение состояний, верно? Итак, вам нужно сохранить его в состоянии реакции как setState (например, target.value).

3. Вы правы, решение состояло в том, чтобы сохранить значения в состоянии thaaaaaaanks.