我对reactjs很新,而且在向我的服务器发出POST请求后,我的状态有了很大的变化。现在我有一个页面,显示一个笔记列表和一个简单的表单,您可以在其中添加注释。
问题是当我将文本放在文本框中并提交表单时,它会发出请求并在一瞬间更新状态,然后返回到原始状态。我现在正在使用硬编码的json数据填充组件,只是为了看到这个组件工作。网络通话后整个应用程序是否刷新?为什么呢?
我意识到我可以在componentDidMount上发出GET请求,以确保应用程序始终更新,但为什么每次呈现此组件时都必须发出两个请求?我不能发出POST请求,如果它是200,请更新状态吗?
这是我的表单组件:
class NewNoteForm extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(note) {
if (this.note.value) {
this.props.handleClick(this.note.value)
}
}
render () {
return (
<form>
<textarea ref={input => this.note = input} id="note"></textarea>
<button id="submit-note" onClick={() => { this.handleSubmit(this.note) }}>Submit</button>
</form>
);
}
}
以下是呈现表单的父组件:
class Incident extends React.Component {
constructor(props) {
super(props);
this.state = {
showAddNoteForm: false,
notes: []
};
this.showNewNoteForm = this.showNewNoteForm.bind(this);
this.handleNewNoteSubmission = this.handleNewNoteSubmission.bind(this);
}
showNewNoteForm() {
this.setState({
showAddNoteForm: true
});
}
handleNewNoteSubmission (noteContent) {
axios.post('/incidents/note')
.then((response) => {
this.setState({
notes: this.state.notes.concat({
'id': 123,
'created_user': 'brian',
'created_at': new Date().toISOString(),
'note': noteContent
})
});
});
}
render() {
return (
<div>
<h1 data-id="incident-header">Incident #{this.props.incident.id}</h1>
<div>
<h3>Notes</h3>
<button onClick={this.showNewNoteForm} id="show-note">Add Note</button>
</div>
{this.state.showAddNoteForm && <NewNoteForm handleClick={this.handleNewNoteSubmission}/>}
<div data-id='incident-notes'>
{
this.state.notes.map( note => {
let noteDetails = {
'id' : note.id,
'content' : note.note,
'created_user' : note.created_user,
'created_at' : this.getDateString(note.created_at)
};
return <Note key={note.id} details={noteDetails} />;
})
}
</div>
</div>
);
}
}
我在这里做错了什么?
答案 0 :(得分:1)
我不知道这是否是唯一的问题,但您必须更改此setState
this.setState({
notes: this.state.notes.concat({
'id': 123,
'created_user': 'brian',
'created_at': new Date().toISOString(),
'note': noteContent
})
});
到
this.setState(prevState => ({
notes: prevState.notes.concat({
'id': 123,
'created_user': 'brian',
'created_at': new Date().toISOString(),
'note': noteContent
})
}));
当您使用先前的状态(或道具)来更新状态时,您需要使用函数参数版本或者您可以处理陈旧数据
答案 1 :(得分:1)
使用表单时,提交表单会触发一个事件(默认情况下为POST操作),导致页面刷新,从而丢失更新后的状态。 您可能有两个解决该问题的方法:
将按钮类型从提交(默认)更改为按钮,因此按此按钮不再导致提交表单。
阻止操作刷新页面。您可以处理由提交触发的事件:onClick={(event) => { event.preventDefault();this.handleSubmit(this.note) }}
这也应该允许您通过在textarea中按Enter来提交表单,因为提交操作将不再刷新您的页面并显示整个反应代码。