我正在学习React并且作为一个学习练习我试图做一个非常基本的页面,其中有一个表单并且您将文本放在输入框中,单击“提交”并且标题将更改为您输入的内容。到目前为止,这是我的代码:
import React, { Component } from 'react';
import './App.css';
class App extends Component {
constructor() {
super();
this.state = {header: 'yeaheheh'}
}
changeHeader(e) {
let newHeader = document.getElementById('input').value();
e.preventDefault();
console.log('submitted');
this.setState(newHeader);
}
render() {
return (
<div>
<h1>{this.state.header}</h1>
<form onSubmit={this.changeHeader.bind(this)} className="change-header-form">
<input id="input" type="text" placeholder="Enter Text Here" />
<input type="submit" value="Submit" />
</form>
</div>
);
}
}
export default App;
首先,当我点击提交时,没有任何反应,我在控制台中出现了错误
Uncaught TypeError: Cannot read property 'setState' of null
然后我意识到我需要将changeHeader
函数绑定到this
,之后我才改变它:
<form onSubmit={this.changeHeader}...
将其更改为
<form onSubmit={this.changeHeader.bind(this)}...
执行此操作后,错误已清除,但我的标题仍然没有更新。I read that强烈反对通过setState更改状态的建议是不好的做法,因为再次调用setState()
可能会改变已更改的状态。 setState
也是一个异步操作,也可以解释为什么我的标题不会改变。
尽管如此,那么处理这个问题的最佳方法是什么?根据我的理解,props
不会有意义,因为这些值直接存储在您的组件中,并且不能动态更新这些参数。我很难理解这些不同数据类型之间的关系以及它们在DOM中的处理方式。
答案 0 :(得分:2)
您正在错误地设置状态。
为了从输入字段中获取数据,您可以通过&#34; ref&#34; 使用controlled
输入元素(通过状态)或uncontrolled
输入元素在下面的例子中使用过。
在受控输入元素中,您将输入元素的值存储在状态中,并通过调用onChange
方法然后通过this.setState({})
设置状态来更改该值。
调用setState
会导致重新呈现,dom
会根据新状态获取更新后的数据。
顺便说一句&#34;参考&#34; 让您可以直接访问dom元素,就像$()
中使用jquery
一样,如果可能的话应该避免因为它会导致很难管理和预测dom
更改。
还有一些情况下使用&#34; refs&#34;推荐
refs有一些很好的用例:
管理焦点,文字选择或媒体播放。
触发势在必行的动画。
与第三方DOM库集成。
class App extends React.Component {
constructor() {
super();
this.state = {header: 'yeaheheh'};
}
changeHeader = (e) => {
e.preventDefault();
let newHeader = this.textInput.value;
console.log('submitted');
this.setState({header : newHeader});
}
render() {
return (
<div>
<h1>{this.state.header}</h1>
<form onSubmit={this.changeHeader} className="change-header-form">
<input id="input" ref={(input) => { this.textInput = input; }} type="text" placeholder="Enter Text Here" />
<input type="submit" value="Submit" />
</form>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('test'));
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="test">
</div>
&#13;
答案 1 :(得分:1)
将this.setState(newHeader);
替换为this.setState({header: newHeader});
。
答案 2 :(得分:1)
在反应文档中查看这篇文章:https://facebook.github.io/react/docs/forms.html#controlled-components。
基本上你想要做的是为输入创建另一个处理程序。每次输入字段发生更改时都会调用此选项,并且state
中的属性将更新。然后,当您提交表格时,您可以使用该新房产并且&#34;合并&#34;它使用setState
成为新标题。
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
header: 'yeaheheh',
next: ''
}
this.changeHeader = this.changeHeader.bind(this);
this.updateNext = this.updateNext.bind(this);
}
changeHeader(e) {
e.preventDefault();
this.setState({
header: this.state.next
});
}
updateNext(e) {
this.setState({
next: e.target.value
});
}
render() {
return (
<div>
<h1>{this.state.header}</h1>
<form onSubmit={this.changeHeader} className="change-header-form">
<input id="input" type="text" placeholder="Enter Text Here" onChange={this.updateNext} />
<input type="submit" value="Submit" />
</form>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('app'));
也许这个垃圾箱会在我试图描述的内容中提供更好的背景。
答案 3 :(得分:0)
您的代码中存在小错误,导致其无法正常工作(this.setState(newHeader)
- &gt; this.setState({header: newHeader});
),但问题是您的代码不是React的惯用语。
您应该使用controlled components而不是像提交jQuery一样从提交表单的输入中获取值。
&#34;受控组件&#34;对于模式而言,输入的状态被映射到应用程序状态是一个愚蠢的名称,因此输入本身就像是有点无状态&#34;。在您的情况下,您需要为您获得的每个文本输入都有单独的组件状态成员。输入控件应如下所示:
<input value={ this.state.inputValue }
onChange={ e => this.setState({ inputValue : e.target.value }) }
/>
现在它已经绑定到您的inputValue
州成员,所以您可以随时从州内取出它。在你的情况下,在表单的提交处理程序上。
那就是它。您的代码必须相应修复。请参阅&#34;受控组件&#34;手册了解更多细节,它是真正重要的React概念。
答案 4 :(得分:0)
您应该像这样修改您的功能..
constructor(props) {
super(props);
_that = this;
}
changeHeader = (e) => {
e.preventDefault();
let newHeader = this.textInput.value;
console.log('submitted');
_that.setState({header : newHeader});
}