【问题标题】:Material Ui - Unable to enter input textfield/ set values on a controlled componentMaterial Ui - 无法在受控组件上输入输入文本字段/设置值
【发布时间】:2023-04-05 03:45:01
【问题描述】:

我尝试使用 inputRef(材质 ui 输入组件)创建自定义输入组件。看起来组件引用正在工作,但在我设置 value 属性 后,我无法在文本字段中输入任何值。我认为这是因为我实现 onchange 事件的方式。我不确定我错过了什么。请帮忙。

这里是codeandbox url

https://codesandbox.io/s/pjlwqvwrvm

【问题讨论】:

    标签: reactjs material-ui


    【解决方案1】:

    实际上,您不需要 onChange 道具来获取更改的值..

    只需从 onchange 中获取值并将值设置为状态value

    另一个错误是你没有创建构造函数,而是把 this.props.value 给了 value prop。就是它没有更新..

    现在我创建了构造函数并将 this.state.value 赋予 value 道具。

    现在您可以在 custominput 组件和您的提交函数中获得 onchanged 值..

    import React from "react";
    import { render } from "react-dom";
    import { Input } from "material-ui-next";
    import trimStart from "lodash/trimStart";
    import PropTypes from "prop-types";
    
    const defaultProps = {
      state: "",
      onChange: () => {} // no need
    };
    
    const propTypes = {
      state: PropTypes.string,
      onChange: PropTypes.func
    };
    
    class App extends React.Component {
      constructor() {
        super();
        this.state = {
          value:''
        }
      }
      handleSubmit(event) {
        event.preventDefault();
        console.log("state: " + this.state.value); //shows onChanged value in console
      }
    
      render() {
        return (
          <div>
            <form onSubmit={this.handleSubmit.bind(this)}>
              <CustomInput
                labelText="State"
                id="state"
                value={this.state.value}
                onChange={e=> {
                  this.setState({value:e.target.value})
                }}
              />
            </form>
          </div>
        );
      }
    }
    
    App.propTypes = propTypes;
    App.defaultProps = defaultProps;
    
    class CustomInput extends React.Component {
      render() {
        const {
          classes,
          formControlProps,
          value,
          onChange,
          labelText,
          id,
          labelProps,
          inputRef,
          inputProps
        } = this.props;
        return (
          <div {...formControlProps}>
            {labelText !== undefined ? (
              <div htmlFor={id} {...labelProps}>
                {labelText}
              </div>
            ) : null}
            <Input
              classes={{
                root: labelText !== undefined ? "" : classes.marginTop
              }}
              id={id}
              value={value} ///////// Fixed ////////
              onChange={onChange}
              inputRef={inputRef}
              {...inputProps}
            />
          </div>
        );
      }
    }
    
    render(<App />, document.getElementById("root"));
    

    这是沙箱中的代码检查它..

    https://codesandbox.io/s/84rjk4m8l8

    【讨论】:

      【解决方案2】:
      1. 您可以继续 inputRef - 然后您的值和 onChange 事件是额外的 - 它被称为不受控制的组件。您可以在这里查看更多信息:https://reactjs.org/docs/uncontrolled-components.html

      2. 或者您可以使用 value 和 onChange 事件来实现 - 并使用受控组件,您可以在此处找到有关受控组件的更多信息:https://reactjs.org/docs/forms.html#controlled-components

      如何用 inputRef 解决(不可控):

      class App extends React.Component {
        handleSubmit = (event) => {
          event.preventDefault();
          console.log("input value: ", this.input.value); // will now show you correct input value
        }
      
        render() {
          return (
            <div>
              <form onSubmit={this.handleSubmit}>
                <CustomInput
                  labelText="State"
                  id="state"
                  inputRef={input => {
                    this.input = input;
                  }}
                />
                <Button onClick={this.handleSubmit} color='primary'>Submit</Button>
              </form>
            </div>
          );
        }
      }
      

      而不是“this.state = input”,而是将输入绑定到其他东西,因为 this.state 是为 React 组件的本地状态保留的,它不会与它一起工作,而不是那样。

      如何通过状态、值和 onChange 事件解决(可控):

      class App extends React.Component {
        constructor(props) {
          super(props);
      
          this.state = {
            value: props.state || ''
          }
        }
      
        handleSubmit = (event) =>{
          event.preventDefault();
          console.log("state: ", this.state.value); // will now show you correct input value
        }
      
        handleChange = (event) => {
          this.setState({value: event.target.value});
        }
      
        render() {
          const {value} = this.state;
      
          return (
            <div>
              <form onSubmit={this.handleSubmit}>
                <CustomInput
                  labelText="State"
                  id="state"
                  onChange={this.handleChange}
                  value={value}
                />
                <Button onClick={this.handleSubmit} color='primary'>Submit</Button>
              </form>
            </div>
          );
        }
      }
      

      请注意,我添加了构造函数并为组件定义了本地状态,并且我正在使用 this.setState 更改状态内部的值(因为状态是不可变的,这是更新它的正确方法)。

      在这两个示例中,您都可以在 handleSubmit 方法中获取输入值,您将使用可控还是不可控组件,这取决于您 :)

      【讨论】:

        【解决方案3】:

        使用value={this.state}value={this.value}

        您的沙盒代码已更新

        https://codesandbox.io/s/qqk2qoxmlj

        【讨论】:

          猜你喜欢
          • 2021-09-02
          • 2019-07-22
          • 1970-01-01
          • 1970-01-01
          • 2012-09-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-03
          相关资源
          最近更新 更多