Размещение настраиваемого компонента радиокнопки внутри группы радиостанций в пользовательском интерфейсе материалов - PullRequest
0 голосов
/ 08 октября 2018

Я хочу иметь список переключателей, при этом один из вариантов - это текстовое поле «Другие», которое позволяет пользователю вводить свой собственный текст.

Здесь у меня есть рабочая песочница из всего, что я хочу сделать:

https://codesandbox.io/s/r4oo5q8q5o

handleChange = event => {
    this.setState({
      value: event.target.value
    });
  };

  selectItem = item => {
    this.setState({
      selectedItem: item
    });
  };

  handleOtherChange = event => {
    this.setState({
      otherText: event.target.value
    });

    this.selectItem(
      //Todo put in right format
      this.state.otherText
    );
  };
  focusOther = () => {
    this.setState({
      value: "Other"
    });

    this.selectItem(this.state.otherText);
  };

  render() {
    const { classes, items } = this.props;
    const { value } = this.state;

    return (
      <div className={classes.root}>
        <Typography>
          {" "}
          Selected item is: {JSON.stringify(this.state.selectedItem)}
        </Typography>

        <FormControl component="fieldset" fullWidth>
          <RadioGroup value={this.state.value} onChange={this.handleChange}>
            {items.map(v => (
              <FormControlLabel
                value={v.name}
                control={<Radio />}
                label={v.name}
                key={v.name}
                onChange={() => this.selectItem(v)}
              />
            ))}

            <FormControlLabel
              value="Other"
              control={<Radio />}
              label={
                <TextField
                  placeholder="other"
                  onChange={this.handleOtherChange}
                  onFocus={this.focusOther}
                />
              }
              onChange={() => this.selectItem(this.state.otherText)}
            />
          </RadioGroup>
        </FormControl>
      </div>
    );
  }
}

Теперь я хочу сделать текст «Другое»коробка свой компонент.

Вот моя попытка:

https://codesandbox.io/s/ryomnpw1o

export default class OtherRadioButton extends React.Component {
  constructor() {
    super();

    this.state = {
      text: null
    };
  }

  handleTextChange = event => {
    this.setState({
      text: event.target.value
    });
    this.props.onChange(this.state.text);
  };
  focusOther = () => {
    this.props.onFocus(this.props.value);
    this.props.onChange(this.state.text);
  };

  render() {
    return (
      <FormControlLabel
        value={this.props.value}
        control={<Radio />}
        label={
          <TextField
            placeholder="other"
            onChange={this.handleTextChange}
            onFocus={this.focusOther}
          />
        }
        onChange={this.focusOther}
      />
    );
  }
}

Используется с:

   <OtherRadioButton
      value="Other"
      onFocus={v => this.setState({ value: v})}
      onChange={v => this.selectItem(v)}
    />

Как видите - значение свободноготекст распространяется нормально, но RadioGroup, похоже, не знает о значении FormGroupLabel.

Почему это так, и как бы я решил это?

1 Ответ

0 голосов
/ 08 октября 2018

Вы можете проверить исходный код RadioGroup здесь .И я написал свой собственный код, чтобы лучше проиллюстрировать, как его можно исправить.Смотрите здесь: https://codesandbox.io/s/mz1wn4n33j

RadioGroup создает некоторые реквизиты для своих потомков FormControlLabel / RadioButton.Создавая свои собственные настраиваемые переключатели в другом компоненте, эти реквизиты не передаются в FormControlLabel / RadioButton.

Вы можете исправить это, передавая реквизиты в FormControlLabel в вашей пользовательской RadioButton.

<FormControlLabel
    value={this.props.value}       //Pass this
    onChange={this.props.onChange} //Pass this one too
    checked={this.props.checked}   //Also this
    control={<Radio name="gender" />}
    label={
      <TextField
        id="standard-bare"
        defaultValue={this.props.defaultValue}
        margin="normal"
        onChange={this.props.onTextChange}
      />
    }
/>
...