Turn to ES6

Summary: Closes https://github.com/facebook/react-native/pull/5460

Reviewed By: svcscm

Differential Revision: D2850417

Pulled By: androidtrunkagent

fb-gh-sync-id: 8ba8bf935de53676cb4930712fabfe832208213f
This commit is contained in:
sunnylqm 2016-01-21 10:37:28 -08:00 committed by facebook-github-bot-3
parent cb4fca3590
commit 7d457b09b4
1 changed files with 50 additions and 48 deletions

View File

@ -43,7 +43,7 @@ For this tutorial we'll be building a simple version of the Movies app that fetc
### Mocking data
Before we write the code to fetch actual Rotten Tomatoes data let's mock some data so we can get our hands dirty with React Native. At Facebook we typically declare constants at the top of JS files, just below the requires, but feel free to add the following constant wherever you like. In `index.ios.js` or `index.android.js` :
Before we write the code to fetch actual Rotten Tomatoes data let's mock some data so we can get our hands dirty with React Native. At Facebook we typically declare constants at the top of JS files, just below the imports, but feel free to add the following constant wherever you like. In `index.ios.js` or `index.android.js` :
```javascript
var MOCKED_MOVIES_DATA = [
@ -54,22 +54,22 @@ var MOCKED_MOVIES_DATA = [
### Render a movie
We're going to render the title, year, and thumbnail for the movie. Since thumbnail is an Image component in React Native, add Image to the list of React requires below.
We're going to render the title, year, and thumbnail for the movie. Since thumbnail is an Image component in React Native, add Image to the list of React imports below.
```javascript
var {
import React, {
AppRegistry,
Image,
StyleSheet,
Text,
View,
} = React;
} from 'react-native';
```
Now change the render function so that we're rendering the data mentioned above rather than hello world.
```javascript
render: function() {
render() {
var movie = MOCKED_MOVIES_DATA[0];
return (
<View style={styles.container}>
@ -196,7 +196,7 @@ Go ahead and press `⌘+R` / `Reload JS` and you'll see the updated view.
Fetching data from Rotten Tomatoes's API isn't really relevant to learning React Native so feel free to breeze through this section.
Add the following constants to the top of the file (typically below the requires) to create the REQUEST_URL used to request data with.
Add the following constants to the top of the file (typically below the imports) to create the REQUEST_URL used to request data with.
```javascript
/**
@ -209,25 +209,26 @@ var REQUEST_URL = 'https://raw.githubusercontent.com/facebook/react-native/maste
Add some initial state to our application so that we can check `this.state.movies === null` to determine whether the movies data has been loaded or not. We can set this data when the response comes back with `this.setState({movies: moviesData})`. Add this code just above the render function inside our React class.
```javascript
getInitialState: function() {
return {
constructor(props) {
super(props);
this.state = {
movies: null,
};
},
}
```
We want to send off the request after the component has finished loading. `componentDidMount` is a function of React components that React will call exactly once, just after the component has been loaded.
```javascript
componentDidMount: function() {
componentDidMount() {
this.fetchData();
},
}
```
Now add `fetchData` function used above to our main component. This method will be responsible for handling data fetching. All you need to do is call `this.setState({movies: data})` after resolving the promise chain because the way React works is that `setState` actually triggers a re-render and then the render function will notice that `this.state.movies` is no longer `null`. Note that we call `done()` at the end of the promise chain - always make sure to call `done()` or any errors thrown will get swallowed.
```javascript
fetchData: function() {
fetchData() {
fetch(REQUEST_URL)
.then((response) => response.json())
.then((responseData) => {
@ -236,22 +237,22 @@ Now add `fetchData` function used above to our main component. This method will
});
})
.done();
},
}
```
Now modify the render function to render a loading view if we don't have any movies data, and to render the first movie otherwise.
```javascript
render: function() {
render() {
if (!this.state.movies) {
return this.renderLoadingView();
}
var movie = this.state.movies[0];
return this.renderMovie(movie);
},
}
renderLoadingView: function() {
renderLoadingView() {
return (
<View style={styles.container}>
<Text>
@ -259,9 +260,9 @@ Now modify the render function to render a loading view if we don't have any mov
</Text>
</View>
);
},
}
renderMovie: function(movie) {
renderMovie(movie) {
return (
<View style={styles.container}>
<Image
@ -274,7 +275,7 @@ Now modify the render function to render a loading view if we don't have any mov
</View>
</View>
);
},
}
```
Now press `⌘+R` / `Reload JS` and you should see "Loading movies..." until the response comes back, then it will render the first movie it fetched from Rotten Tomatoes.
@ -290,23 +291,23 @@ Let's now modify this application to render all of this data in a `ListView` com
Why is a `ListView` better than just rendering all of these elements or putting them in a `ScrollView`? Despite React being fast, rendering a possibly infinite list of elements could be slow. `ListView` schedules rendering of views so that you only display the ones on screen and those already rendered but off screen are removed from the native view hierarchy.
First things first: add the `ListView` require to the top of the file.
First things first: add the `ListView` import to the top of the file.
```javascript
var {
import React, {
AppRegistry,
Image,
ListView,
StyleSheet,
Text,
View,
} = React;
} from 'react-native';
```
Now modify the render function so that once we have our data it renders a ListView of movies instead of a single movie.
```javascript
render: function() {
render() {
if (!this.state.loaded) {
return this.renderLoadingView();
}
@ -318,28 +319,29 @@ Now modify the render function so that once we have our data it renders a ListVi
style={styles.listView}
/>
);
},
}
```
The `dataSource` is an interface that `ListView` is using to determine which rows have changed over the course of updates.
You'll notice we used `dataSource` from `this.state`. The next step is to add an empty `dataSource` to the object returned by `getInitialState`. Also, now that we're storing the data in `dataSource`, we should no longer use `this.state.movies` to avoid storing data twice. We can use boolean property of the state (`this.state.loaded`) to tell whether data fetching has finished.
You'll notice we used `dataSource` from `this.state`. The next step is to add an empty `dataSource` to the object returned by `constructor`. Also, now that we're storing the data in `dataSource`, we should no longer use `this.state.movies` to avoid storing data twice. We can use boolean property of the state (`this.state.loaded`) to tell whether data fetching has finished.
```javascript
getInitialState: function() {
return {
constructor(props) {
super(props);
this.state = {
dataSource: new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2,
}),
loaded: false,
};
},
}
```
And here is the modified `fetchData` method that updates the state accordingly:
```javascript
fetchData: function() {
fetchData() {
fetch(REQUEST_URL)
.then((response) => response.json())
.then((responseData) => {
@ -349,7 +351,7 @@ And here is the modified `fetchData` method that updates the state accordingly:
});
})
.done();
},
}
```
Finally, we add styles for the `ListView` component to the `styles` JS object:
@ -377,17 +379,16 @@ There's still some work to be done to make it a fully functional app such as: ad
* Sample React Native App
* https://github.com/facebook/react-native
*/
'use strict';
var React = require('react-native');
var {
import React, {
AppRegistry,
Component,
Image,
ListView,
StyleSheet,
Text,
View,
} = React;
} from 'react-native';
var API_KEY = '7waqfqbprs7pajbz28mqf6vz';
var API_URL = 'http://api.rottentomatoes.com/api/public/v1.0/lists/movies/in_theaters.json';
@ -395,21 +396,22 @@ var PAGE_SIZE = 25;
var PARAMS = '?apikey=' + API_KEY + '&page_limit=' + PAGE_SIZE;
var REQUEST_URL = API_URL + PARAMS;
var AwesomeProject = React.createClass({
getInitialState: function() {
return {
class AwesomeProject extends Component {
constructor(props) {
super(props);
this.state = {
dataSource: new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2,
}),
loaded: false,
};
},
}
componentDidMount: function() {
componentDidMount() {
this.fetchData();
},
}
fetchData: function() {
fetchData() {
fetch(REQUEST_URL)
.then((response) => response.json())
.then((responseData) => {
@ -419,9 +421,9 @@ var AwesomeProject = React.createClass({
});
})
.done();
},
}
render: function() {
render() {
if (!this.state.loaded) {
return this.renderLoadingView();
}
@ -433,9 +435,9 @@ var AwesomeProject = React.createClass({
style={styles.listView}
/>
);
},
}
renderLoadingView: function() {
renderLoadingView() {
return (
<View style={styles.container}>
<Text>
@ -443,9 +445,9 @@ var AwesomeProject = React.createClass({
</Text>
</View>
);
},
}
renderMovie: function(movie) {
renderMovie(movie) {
return (
<View style={styles.container}>
<Image
@ -458,7 +460,7 @@ var AwesomeProject = React.createClass({
</View>
</View>
);
},
}
});
var styles = StyleSheet.create({