POST ajax call

时间:2018-03-21 14:22:12

标签: javascript ajax reactjs

我对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>
    );
  }
}

我在这里做错了什么?

2 个答案:

答案 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操作),导致页面刷新,从而丢失更新后的状态。 您可能有两个解决该问题的方法:

  1. 将按钮类型从提交(默认)更改为按钮,因此按此按钮不再导致提交表单。

  2. 阻止操作刷新页面。您可以处理由提交触发的事件:onClick={(event) => { event.preventDefault();this.handleSubmit(this.note) }} 这也应该允许您通过在textarea中按Enter来提交表单,因为提交操作将不再刷新您的页面并显示整个反应代码。