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:
parent
cb4fca3590
commit
7d457b09b4
|
@ -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({
|
||||
|
|
Loading…
Reference in New Issue