Выбор пользовательского интерфейса не показывает ярлык - PullRequest
0 голосов
/ 01 июля 2018

У меня чертовски много времени с Материалом пользовательского интерфейса «Выбор» - около 10 часов, пытаясь заставить его работать так, как мне хотелось бы. Буду очень признателен за помощь.

Этот вопрос относится к предыдущему: Выберите MenuItem, который не отображается, когда JSX сохранен в состояние , и я подозреваю, что, если на этот вопрос ответили «почему», я мог бы получить лучшее представление о что происходит.

То, что я пытаюсь сделать, - это выбор, который делает следующие нормальные вещи:

  • имеет все вкусности пользовательского интерфейса (показывает вопрос в выбранном месте, затем перемещает вопрос меньше и удаляет его после выбора ненулевой выбор)
  • при выборе чего-либо появляется метка (как и следовало ожидать в выпадающий), а не пустой (как я испытал - проверьте предыдущий вопрос)
  • в консоли нет предупреждений о том, что значение не определено
  • когда я выбираю что-то после выбора, я не хочу, чтобы метка вопроса переместилась обратно на верх ответа так: selected option and question label on top of each other
  • Мне нужна опция none, которая возвращает выбор обратно в пустое состояние. форма (то есть метка вопроса показывает в нормальном размере в выберите)
  • Я могу установить выбор, который будет выбран по умолчанию

Это не должно быть трудным заданием, но я не могу этого добиться. Это довольно неловко.

  • Затем, выбрав что-то, я хочу сохранить этот выбор (вместе с другими вариантами выбора), чтобы заявить (чтобы я мог сохранить его в localStorage, чтобы при обновлении страницы более крупная форма не «сбрасывалась»

В любом случае, в настоящее время у меня есть этот JSX - фактически вырезанный и вставленный из демонстрационных материалов пользовательского интерфейса с картой для MenuItems:

<FormControl className={classes.formControl}>
<InputLabel htmlFor={this.props.label}>{this.props.label}</InputLabel>
<Select
    value={this.state.selectLabel}
    onChange={this.handleSelectChange}
    inputProps={{
        name: 'selectLabel',  
        id: this.props.label,
    }}
>
{this.props.value.map(valueLabelPair =>
                <MenuItem
                    key={this.props.XMLvalue + "_" + valueLabelPair.label}
                    value={valueLabelPair.value}
                >
                    {valueLabelPair.label}
                </MenuItem>
            )}
</Select>
</FormControl>

handleSelectChange выглядит следующим образом - опять же, точно так же, как демонстрация пользовательского интерфейса материала.

handleSelectChange = event => {
    this.setState({ [event.target.name]: event.target.value });
};

Этот вид работ, за исключением консоли, выдает следующую ошибку:

Неудачный тип пропеллера: пропеллер value помечен как требуется в SelectInput, но его значение равно undefined.

и выбранный вариант и метка вопроса располагаются друг над другом после щелчка, например: selected option and question label on top of each other

Далее, если я попытаюсь добавить этот код (в функцию componentDidMount) с целью возможности передать параметр "selected" / default ...

componentDidMount() {
    for (var i = 0; i < this.props.value.length; i++) {
        if(this.props.value[i].selected) {
            // *works* console.log("selected found: " + this.props.value[i].label);
            this.setState({selectLabel:this.props.value[i].label});
        }
    }
}

он не обновляет, дает мне ответ по умолчанию, а также дает мне следующую дополнительную ошибку в консоли (в дополнение ко всем вышеуказанным проблемам):

Предупреждение: компонент изменяет неконтролируемый ввод скрытого типа быть под контролем. Элементы ввода не должны переключаться с неконтролируемого контролируемый (или наоборот). Выберите между использованием контролируемого или неуправляемый элемент ввода для времени жизни компонента.

Чего мне не хватает?

Ответы [ 2 ]

0 голосов
/ 23 марта 2019

Просто определите selectLabel в конструкторе:

constructor () {
    super()
    this.state = {
        selectLabel:'',
    }
}
0 голосов
/ 06 июля 2018

Я не уверен, почему вышеприведенное решение не сработало.

Однако я перестроил элемент Select для возврата элементов «option» вместо элементов «MenuItem» со следующей функцией:

buildSelectOptions(optionsPairs) {  // note, this references props and blank option could be split out for reuse
    var JSX_return = [];

    if (this.props.includeBlank && this.props.includeBlank === true) {
        JSX_return.push(<option key="nada" value="" />);
    }

    for (var optionLabel in optionsPairs) {
        JSX_return.push(<option key={optionLabel} value={optionsPairs[optionLabel]}>{optionLabel}</option>);
    }
    return JSX_return;
}

Мой рендер теперь выглядит так:

                <FormControl className={classes.formControl}>
                    <InputLabel htmlFor="age-native-simple">{this.props.label}</InputLabel>
                    <Select
                        native
                        value={this.state.value}
                        onChange={this.handleSelectChange('value')}
                        inputProps={{
                            name: this.props.label,
                            id: this.props.id,
                          }}
                    >
                        {this.buildSelectOptions(this.props.options)}

                    </Select>
                    <FormHelperText>{this.props.helperText}</FormHelperText>
                </FormControl>

И обработчик событий выглядит так:

handleSelectChange = name => event => {  //FUTURE: combine the handlers  (or split out question types to sub-components)
    this.setState({ [name]: event.target.value },
        () => this.props.stateChangeHandler(this)
    );
};

реквизиты, переданные этому объекту, выглядят так:

    {
        "key": "test4",
        "id": "test4",
        "label": "Question Label 4",
        "XMLValue": "XMLQ4",
        "type": "DropDown",
        "includeBlank": true,
        "helperText": "PCodes FTW!",
        "options": {
            "No oe": "NA",
            "My1": "One",
            "My2": "Two",
            "My3": "three"
        },
        "value": "One"
    }

Одной из ключевых концепций для меня было узнать, что поле value в элементе Select должно указывать на элемент в this.state. Затем onChange должен передать имя этой переменной состояния (которую, как ни странно, я назвал «value») в функцию eventHandler.

Заголовок функции с двойной стрелкой (функция curry) функции handleSelectChange все еще смущает меня ... (Я не понимаю, как туда попадает свойство 'event', учитывая, что я вызываю эту функцию с одним параметр) ... но это работает на данный момент, и я могу попытаться изменить рефакторинг в синтаксис, который мне удобен (то есть: function(a, b) { *do something* }) в будущем. (Да ....)

Надеюсь, это кому-нибудь пригодится ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...