代码之家  ›  专栏  ›  技术社区  ›  dwjohnston

将自定义单选按钮组件放入材质UI中的单选组中

  •  3
  • dwjohnston  · 技术社区  · 7 年前

    我想有一个单选按钮列表,其中一个选项是一个自由风格的'其他'文本框,让用户输入自己的文本。

    这里我有一个工作沙盒,里面有我想做的一切:

    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>
        );
      }
    }
    

    现在我要做的是让“Other”文本框成为自己的组件。

    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 回复  |  直到 7 年前
        1
  •  6
  •   Ramil Amparo    7 年前

    您可以检查RadioGroup源代码 here . https://codesandbox.io/s/mz1wn4n33j

    RadioGroup为其FormControlLabel/RadioButton子级创建一些道具。通过在不同组件中创建自己的自定义单选按钮,这些道具不会传递给FormControlLabel/RadioButton。

    您可以通过将道具传递到自定义单选按钮中的FormControlLabel来修复这些问题。

    <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}
          />
        }
    />