Javascript 反应输入元素:值与默认值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42807901/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 01:26:39  来源:igfitidea点击:

React Input Element : Value vs Default Value

javascriptreactjsfrontend

提问by vidihermes

i am new in React and REDUX, i just develop a simple react app, and now i face a problem, when i render an input element within my component if i set the element "value" it become read-only but if i set the value on "defaultValue" it will never update again when i re-update my state.

我是 React 和 REDUX 的新手,我只是开发了一个简单的 React 应用程序,现在我面临一个问题,当我在组件中渲染输入元素时,如果我将元素设置为“值”,它将变为只读,但如果我设置了“defaultValue”上的值当我重新更新我的状态时它永远不会再次更新。

Here is my code :

这是我的代码:

    import React from "react";
    export default class EditForm extends React.Component {

    editTransaction(event) {

        var transaction = this.props.transaction;

        event.preventDefault();
        var NewTransaction = {
            transactions_data: {
                amount: this.refs.amount.value
            }
        }

        this.props.editTransaction(NewTransaction, transaction.id);
    }

    closeForm() {
        this.props.closeForm();
    }

    render() {
        var {amount}=this.props.transaction;
        return (
            <div>
                <br/>
                <h4>Edit Transaction</h4>
                <div className="btn btn-danger pull-right" onClick={this.closeForm.bind(this)}>close</div>
                <div className="clearfix"></div>
                <form onSubmit={this.editTransaction.bind(this)}>
                    <div>
                        <label for="amount">Amount</label>
                        <input value={amount} onChange={(value) => this.onChange(value)} className="form-control"
                               id="amount" name="amount" type="number"
                               ref="amount"/>
                    </div>
                    <br/>
                    <br/>
                    <input className="btn btn-info" type="submit" value="submit"/>
                </form>
            </div>
        );
    }
}

and then i found out if i make an error out of this by adding onChange={(value) => this.onChange(value)}on my input element, it works properly ( it updating while the props or state is updating, and i can re-type the value), but i think this is not a proper solution, because it cause errors on my browser console. It is because "this.onChange" function does not exist.

然后我发现我是否通过添加onChange={(value) => this.onChange(value)}输入元素来解决这个错误 ,它可以正常工作(它会在更新道具或状态时更新,我可以重新输入值),但我认为这不是一个正确的解决方案,因为它会导致我的浏览器控制台出错。这是因为“this.onChange”函数不存在。

please kindly help me to solve this problem, and thanks in advance

请帮助我解决这个问题,并提前致谢

Regards,

问候,

Vidy

维迪

回答by Shubham Khatri

The reason your input doesn't work is because you need to definethe onChangefunction which actually sets the statewith the updated value. You can probably do it inline since it only needs on statement like

您的输入不起作用的原因是因为您需要实际使用更新值defineonChange函数sets the state。您可能可以内联进行,因为它只需要像这样的语句

<input type="text" value={this.state.inputVal} onChange={(e) => {this.setState({inputVal: e.target.value})}} />

However I would recommend you to use an onChangemethod as you can handle multiple inputs together with it and it looks cleaner

但是我建议您使用一种onChange方法,因为您可以使用它处理多个输入并且看起来更干净

class EditForm extends React.Component {

    constructor() {
        super();
        this.state = {
        
        }
    }
    onChange(e) {
         this.setState({[e.target.name]: e.target.value})
    }
    editTransaction(event) {

        var transaction = this.props.transaction;

        event.preventDefault();
        var NewTransaction = {
            transactions_data: {
                amount: this.refs.amount.value
            }
        }

        this.props.editTransaction(NewTransaction, transaction.id);
    }

    closeForm() {
        this.props.closeForm();
    }

    render() {
       
        return (
            <div>
                <br/>
                <h4>Edit Transaction</h4>
                <div className="btn btn-danger pull-right" onClick={this.closeForm.bind(this)}>close</div>
                <div className="clearfix"></div>
                <form onSubmit={this.editTransaction.bind(this)}>
                    <div>
                        <label for="amount">Amount</label>
                        <input value={this.state.amount} onChange={(value) => this.onChange(value)} className="form-control"
                               id="amount" name="amount" type="number"
                               ref="amount"/>
                         <input value={this.state.amount1} onChange={(value) => this.onChange(value)} className="form-control"
                               id="amount1" name="amount1" type="number"
                               ref="amount"/>
                    </div>
                    <br/>
                    <br/>
                    <input className="btn btn-info" type="submit" value="submit"/>
                </form>
            </div>
        );
    }
}

ReactDOM.render(<EditForm/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react-dom.min.js"></script>
<div id="app"></div>

回答by Turtle

You need to define an onChange method, if you are using redux that could be an action that updates your component state via a reducer. An easier method using simple state with es6 is shown below. Furthermore, you are getting the value from the input field via refwhich is discouraged by Facebook. This should also give you an error because you are trying to control and uncontrolled component.

您需要定义一个 onChange 方法,如果您使用的是 redux,它可能是一个通过 reducer 更新组件状态的操作。下面显示了使用带有 es6 的简单状态的更简单的方法。此外,您正在从refFacebook 不鼓励的输入字段中获取值。这也应该给你一个错误,因为你试图控制和不受控制的组件。

Here's a linkto the form documentation for further reading.

这是表单文档的链接以供进一步阅读。

class Foo extends React.Component { 
  constructor(props) {
    super(props);
    this.state = ({
      inputVal: '',
    });
  }
  onChange = (e) => {
    this.setState({ [e.target.name]: e.target.value });
  }
  handleSubmit = (event) => {
    event.preventDefault();
    console.log(this.state.inputVal);
  }
  render() {
    return (
      <div>
        <input type="text" value={this.state.inputVal} onChange={this.onChange} />
      </div>
    );
  }
}

回答by Forrest

I was tinkering with this and found a really simple solution:

我正在修补这个并找到了一个非常简单的解决方案:

class App extends Component {

constructor(props) {
    super(props)
    this.enterText = this.enterText.bind(this)
    this.state = {
        userNameText: 'user name',
        pswdText: 'pswd',
        textEntry: false
    }
}

async enterText() {
    if (!this.state.textEntry) {
        await this.clearText()
        this.setState({textEntry: true})
    }
}

clearText() {
    this.setState({
        userNameText: '',
        pswdText: ''
    })
}

render() {
    return (
        <div className="App">
            <div className="App-header">
                <h1 className="App-title">
                    Welcome
                </h1>
            </div>
            <div className="login-fields">
                <LoginFields userNameText={this.state.userNameText} pswdText={this.state.pswdText} onFocus={this.enterText} />
            </div>
        </div>
    )
}
}

So, upon initial render(), the state of the fields are whatever is hard coded in the constructor. When the user clicks in either the name or pswd box (these could easily be separated), both are cleared with clearText() and then both are set to null with allowText(). Once set to null, the user input text is accepted.

因此,在初始 render() 时,字段的状态是构造函数中硬编码的任何内容。当用户单击 name 或 pswd 框时(它们很容易被分开),两者都用 clearText() 清除,然后用 allowText() 将两者设置为 null。一旦设置为 null,用户输入的文本就会被接受。

Make sure the LoginFields component has this in the input:

确保 LoginFields 组件在输入中有这个:

onFocus={this.props.onFocus}

onFocus={this.props.onFocus}