React Router - 历史首先触发而不是等待
React Router - History fires first rather waiting
我遇到了一个问题,方法触发的顺序不正确。
我不知道如何让 this.props.history.pushState(null, '/authors');
在 saveAuthor() 方法中等待。
将不胜感激。
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)
这是因为您的 postAuthor 方法内部有一个对 fetch()
的异步调用。这时您可能希望将函数作为回调传递给该函数,然后在 fetch
调用的 "completion" 回调中调用该函数。代码看起来像这样:
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');
});
};
Fetch 是一个异步函数。在请求完成之前继续执行到下一行。请求完成后,您需要将代码排队到 运行。最好的方法是让你的 postAuthor 方法 return 成为承诺,然后在调用者中使用承诺的 .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');
};
我遇到了一个问题,方法触发的顺序不正确。
我不知道如何让 this.props.history.pushState(null, '/authors');
在 saveAuthor() 方法中等待。
将不胜感激。
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)
这是因为您的 postAuthor 方法内部有一个对 fetch()
的异步调用。这时您可能希望将函数作为回调传递给该函数,然后在 fetch
调用的 "completion" 回调中调用该函数。代码看起来像这样:
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');
});
};
Fetch 是一个异步函数。在请求完成之前继续执行到下一行。请求完成后,您需要将代码排队到 运行。最好的方法是让你的 postAuthor 方法 return 成为承诺,然后在调用者中使用承诺的 .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');
};