使用React的'ref'属性和Material-UI

时间:2018-04-18 09:32:04

标签: javascript reactjs material-ui

我正在尝试使用材质UI中TextField上的React的“ref”属性来访问输入数据。通过'inputRef'或'inputProps'似乎没有一种简单的方法。

下面的示例显示了第26行使用inputProps。将TextField的名称分配给'ref'属性似乎不会产生有效的对象。

使用“inputRef”,根据Material-ui文档强制使用函数,尝试将字段数据作为属性传递也不起作用。例如:(txt => this.name = txt)

有没有人找到解决方案?

class MediaForm extends Component {
  constructor (props) {
    super(props)
    this.state = {}
    this.handleSubmit = this.handleSubmit.bind(this)
  }

  handleSubmit (e) {
    const { title, colour } = this.refs
    e.preventDefault()
    window.alert(`New colour: ${title.value} ${colour.value}`)
  }

  render () {
    const { classes } = this.props
    return (
      <form className={classes.root}
        onSubmit={this.handleSubmit}>
        <div className={classes.field}>
          <TextField
            name='title'
            type='text'
            label='Title'
            placeholder='Movie title...'
            autoFocus
            inputProps={{ref: this.name}}
            required />
        </div>
        <div className={classes.field}>
          <Tooltip title='Add a colour the reflects the mood of the film'>
            <TextField
              name='colour'
              type='color'
              label='Mood'
              inputProps={{ref: this.name}}
              required />
          </Tooltip>
        </div>
        <Button
          variant='raised'
          color='primary'
          className={classes.button}>
          ADD
        </Button>
      </form>
    )
  }
}

MediaForm.propTypes = {
  classes: PropTypes.object.isRequired
}

export default withRoot(withStyles(styles)(MediaForm))

2 个答案:

答案 0 :(得分:2)

你不需要参考。 submit事件包含表单作为目标。您可以通过form.elements

访问表单中的输入
handleSubmit (event) {
    const { title, colour } = event.currentTarget.elements;
    event.preventDefault();
    window.alert(`New colour: ${title.value} ${colour.value}`);
}

您的参考问题:this.name指的是什么?您没有在任何地方声明它,因此它是undefined。将undefined传递给ref道具无效。另外,如何将两个输入引用绑定到同一个实例属性name。您是否知道渲染函数中的this引用了MediaForm组件的实例,因此this.name是组件实例上的属性name(未定义) ?

如果您想获得每个输入的个人参考,您应该使用callback pattern。请注意String refs are deprecated,不应使用:

render() {
    return(
        <TextField
            name='title'
            type='text'
            label='Title'
            placeholder='Movie title...'
            autoFocus
            inputProps={{ref: input => this.titleInput = input}}
            required 
        />
    );
}

修改

您可能需要的内容称为controlled component。在这种模式中,您的父组件会跟踪它的子项(通常是输入)的值:

class MediaForm extends Component {
    constructor(props) {
        super(props);
        this.state = {
            title: '',
            colour: '',
        };
    }

    handleChange = event => {
        const {name, value} = event.currentTarget;
        this.setState({[name]: value});
    };

    handleSubmit = event => {
        event.preventDefault();
        const {title, colour} = this.state;
        window.alert(`New colour: ${title} ${colour}`);
    };

    render() {
        const {classes} = this.props;
        const {title, colour} = this.state;

        return (
            <form className={classes.root} onSubmit={this.handleSubmit}>
                <div className={classes.field}>
                    <TextField
                        name="title"
                        type="text"
                        value={title}
                        onChange={this.handleChange}
                        label="Title"
                        placeholder="Movie title..."
                        required
                    />
                </div>
                <div className={classes.field}>
                    <Tooltip title="Add a colour the reflects the mood of the film">
                        <TextField
                            name="colour"
                            type="color"
                            value={colour}
                            onChange={this.handleChange}
                            label="Mood"
                            required
                        />
                    </Tooltip>
                </div>
                <Button
                    type="submit"
                    variant="raised"
                    color="primary"
                    className={classes.button}
                >
                    ADD
                </Button>
            </form>
        );
    }
}

Edit kxm42q76vv

现在,您的父母可以通过this.state.titlethis.state.colour完全控制并访问每项输入的值。这里也不需要任何参考。

答案 1 :(得分:0)

class MediaForm extends Component {
  refs = {}  // <____ notice this
  constructor (props) {
    super(props)
    this.state = {}
    this.handleSubmit = this.handleSubmit.bind(this)
  }

  handleSubmit (e) {
    const { title, colour } = this.refs
    e.preventDefault()
    window.alert(`New colour: ${title.value} ${colour.value}`)
  }

  render () {
    const { classes } = this.props
    return (
      <form className={classes.root}
        onSubmit={this.handleSubmit}>
        <div className={classes.field}>
          <TextField
            inputProps={{ref => this.refs.title = ref}}
            name='title'
            type='text'
            label='Title'
            placeholder='Movie title...'
            autoFocus
            required />
        </div>
        <div className={classes.field}>
          <Tooltip title='Add a colour the reflects the mood of the film'>
            <TextField
              name='colour'
              inputProps={{ref => this.refs.colour = ref}}
              type='color'
              label='Mood'
              required />
          </Tooltip>
        </div>
        <Button
          variant='raised'
          color='primary'
          className={classes.button}>
          ADD
        </Button>
      </form>
    )
  }
}

MediaForm.propTypes = {
  classes: PropTypes.object.isRequired
}

export default withRoot(withStyles(styles)(MediaForm))