-
-
Notifications
You must be signed in to change notification settings - Fork 26.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add docs for using Promises and making AJAX requests #531
Changes from 2 commits
9e460ac
358992f
012ca18
7af6adf
c068273
a94a24c
12aca13
8ec8ef0
d998dde
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ You can find the most recent version of this guide [here](https://github.com/fac | |
- [Adding Bootstrap](#adding-bootstrap) | ||
- [Adding Flow](#adding-flow) | ||
- [Adding Custom Environment Variables](#adding-custom-environment-variables) | ||
- [Fetching AJAX Requests](#fetching-ajax-requests) | ||
- [Integrating with a Node Backend](#integrating-with-a-node-backend) | ||
- [Proxying API Requests in Development](#proxying-api-requests-in-development) | ||
- [Adding `<meta>` Tags](#adding-meta-tags) | ||
|
@@ -463,6 +464,62 @@ if (process.env.NODE_ENV !== 'production') { | |
} | ||
``` | ||
|
||
## Fetching AJAX Requests | ||
|
||
This project includes a [fetch polyfill](https://github.com/github/fetch), which makes it easier to make web requests. | ||
|
||
The `fetch` function allows to easily makes AJAX requests. It takes in a URL as an input and returns a `Promise` that resolves to a `Response` object. You can find more information about `fetch` [here](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch). | ||
|
||
|
||
__About Promises:__ This project also includes a [Promise polyfill](https://github.com/then/promise) which provides a full implementation of Promises/A+. A Promise represents the eventual result of an asynchronous operation, you can find more information about Promises [here](https://www.promisejs.org/) and [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). | ||
|
||
You can make a GET request like this: | ||
```javascript | ||
class MyComponent extends Component { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's add all necessary imports here so people can copy and paste. Same in next block. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we make this a drop-in replacement for App.js that ships with this project? Instead of UserGists maybe map over their names in a |
||
state = {} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's not use class properties here yet. People might get confused. We'll document them later. |
||
|
||
componentDidMount() { | ||
this.fetchGists(); | ||
} | ||
|
||
fetchGists() { | ||
fetch('https://api.github.com/users/octocat/gists') | ||
.then((response) => response.json()) | ||
.then((gists) => this.setState({ gists })) | ||
.catch((error) => console.log('Error', error)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a subtle problem here. If setState() throws (for example due to an error in render()), we will get into the catch handler. It is then easy to miss or ignore that error, and now React is in an inconsistent state. Instead, let's put catch() before the second then(). This way we only catch network errors. We want errors in setState() to stay unhandled. Let's make catch() return an empty array. Then we can safely use its result in setState() whether it succeeded or failed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also note that So to handle HTTP errors, you'll also have to check There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, @insin mentioned this later in a comment too. We should handle both |
||
} | ||
|
||
render() { | ||
return <UserGists gists={this.state.gists} />; | ||
} | ||
} | ||
``` | ||
|
||
You can also use the `async/await` syntax to fetch data. [Here](https://zeit.co/blog/async-and-await) is an introduction to it. | ||
```javascript | ||
class MyComponent extends Component { | ||
state = {} | ||
|
||
componentDidMount() { | ||
this.fetchGists(); | ||
} | ||
|
||
async fetchGists() { | ||
try { | ||
const response = await fetch('https://api.github.com/users/octocat/gists'); | ||
const gists = await response.json(); | ||
this.setState({ gists }); | ||
} catch(error) { | ||
console.log('Error', error); | ||
} | ||
} | ||
|
||
render() { | ||
return <UserGists gists={this.state.gists} />; | ||
} | ||
} | ||
``` | ||
|
||
## Integrating with a Node Backend | ||
|
||
Check out [this tutorial](https://www.fullstackreact.com/articles/using-create-react-app-with-a-server/) for instructions on integrating an app with a Node backend running on another port, and using `fetch()` to access it. You can find the companion GitHub repository [here](https://github.com/fullstackreact/food-lookup-demo). | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's say "the global fetch function" instead to make it clear you don't need to import it.