反应路由器 - 历史首先触发而不是等待

时间:2016-02-10 01:14:45

标签: javascript reactjs react-router

嘿,伙计们在这里遇到的问题是方法不按正确顺序发射。 我无法弄清楚如何在saveAuthor()方法中进行this.props.history.pushState(null, '/authors');等待。

将非常感谢帮助。

import React, { Component } from 'react';
import AuthorForm from './authorForm';
import { History } from 'react-router';

const source = 'http://localhost:3000/authors';


// History Mixin Component Hack
function connectHistory (Component) {
  return React.createClass({
    mixins: [ History ],
    render () {
      return <Component {...this.props} history={this.history}/>
    }
  })
}


// Main Component
class ManageAuthorPage extends Component {
  state = {
    author: { id: '', firstName: '', lastName: '' }
  };

  setAuthorState(event) {
    let field = event.target.name;
    let value = event.target.value;
    this.state.author[field] = value;
    return this.setState({author: this.state.author});
  };

  generateId(author) {
    return `${author.firstName.toLowerCase()}-${author.lastName.toLowerCase()}`
  };

// Main call to the API

  postAuthor() {
    fetch(source, {
        method: 'post',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
        body: JSON.stringify({
            id: this.generateId(this.state.author),
            firstName: this.state.author.firstName,
        lastName: this.state.author.lastName
        })
    });
  };

  // Calling Save author method but the this.props.history goes first rather than this.postAuthor();

  saveAuthor(event) {
    event.preventDefault();
    this.postAuthor();
    this.props.history.pushState(null, '/authors');
  };

  render() {
    return (
      <AuthorForm
        author={this.state.author}
        onChange={this.setAuthorState.bind(this)}
        onSave={this.saveAuthor.bind(this)}
      />
    );
  }
}



export default connectHistory(ManageAuthorPage)

2 个答案:

答案 0 :(得分:2)

Fetch是一个异步函数。在请求完成之前,执行继续到下一行。您需要将代码排队以在请求完成后运行。最好的方法是让你的postAuthor方法返回promise,然后在调用者中使用promise的.then方法。

class ManageAuthorPage extends Component {
// ...
  postAuthor() {
    return fetch(source, {
        method: 'post',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
        body: JSON.stringify({
            id: this.generateId(this.state.author),
            firstName: this.state.author.firstName,
        lastName: this.state.author.lastName
        })
    });
  };

  saveAuthor(event) {
    event.preventDefault();
    this.postAuthor().then(() => {
      this.props.history.pushState(null, '/authors');
    });
  };
// ...
}

如果您正在使用支持ES7异步功能的转换器,那么您甚至可以在saveAuthor方法中执行此操作,该方法相同且更易于阅读:

  async saveAuthor(event) {
    event.preventDefault();
    await this.postAuthor();
    this.props.history.pushState(null, '/authors');
  };

答案 1 :(得分:1)

所以这是因为你的postAuthor方法在其中有fetch()的异步调用。在这个时候你想要传递一个函数作为函数的回调,然后在&#34;完成&#34;内部调用该函数。回调fetch电话。代码看起来像这样:

postAuthor(callback) {
  fetch(source, {
    /* Methods, headers, etc. */
  }, () => {
    /* Invoking the callback function that you passed */
    callback();
  });
);

saveAuthor(event) {
  event.preventDefault(); 
  /* Pass in a function to be invoked from within postAuthor when it is complete */
  this.postAuthor(() => {
    this.props.history.pushState(null, '/authors');
  });
};