Skip to content

Commit

Permalink
Finish tutorial draft
Browse files Browse the repository at this point in the history
  • Loading branch information
arasmussen committed Mar 26, 2015
1 parent b900ce2 commit 12a7c2e
Show file tree
Hide file tree
Showing 6 changed files with 197 additions and 10 deletions.
2 changes: 0 additions & 2 deletions Examples/Movies/SearchScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ var TimerMixin = require('react-timer-mixin');
var MovieCell = require('./MovieCell');
var MovieScreen = require('./MovieScreen');

var fetch = require('fetch');

var API_URL = 'http://api.rottentomatoes.com/api/public/v1.0/';
var API_KEYS = ['7waqfqbprs7pajbz28mqf6vz', 'y4vwv8m33hed9ety83jmv52f'];

Expand Down
205 changes: 197 additions & 8 deletions docs/Tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ next: videos

This is a tutorial that aims to get you up to speed with writing iOS apps using React Native. If you want to learn what React Native is and why Facebook built it, check out this blog post: **[INSERT BLOG POST URL]**.

We assume you have experience writing websites with ReactJS. If not, you can learn about ReactJS [here](http://facebook.github.io/react/).
We assume you have experience writing websites with React. If not, you can learn about React [here](http://facebook.github.io/react/).


## Setup
Expand Down Expand Up @@ -109,6 +109,10 @@ And lastly we need to apply this still to the Image component:

Press cmd+R and the image should now render.

Screenshot:

<img src="https://github.com/facebook/react-native/raw/master/docs/images/TutorialMock.png" alt="screenshot" width="320px" />


### Add some styling

Expand Down Expand Up @@ -178,15 +182,13 @@ This is pretty straightforward if you've ever seen CSS before. Make the title la

Go ahead and press cmd+R and you'll see the updated view.

### Fetching real data
Screenshot:

Fetching data from Rotten Tomatoes's API isn't really relevant to learning React Native so feel free to breeze through this section.
<img src="https://github.com/facebook/react-native/raw/master/docs/images/TutorialStyledMock.png" alt="screenshot" width="320px" />

Require the fetch module which is used to make an HTTP request to rotten tomatoes's API.
### Fetching real data

```javascript
var fetch = require('fetch');
```
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.

Expand All @@ -203,7 +205,7 @@ Add some initial state to our application so that we can check this.state.movies
```javascript
getInitialState: function() {
return {
movies: null
movies: null,
};
},
```
Expand Down Expand Up @@ -272,6 +274,193 @@ Now modify the render function to render a loading view if we don't have any mov

Now press cmd+R and you should see "Loading movies..." until the response comes back, then it will render the first movie it fetched from Rotten Tomatoes.

Screenshot:

<img src="https://github.com/facebook/react-native/raw/master/docs/images/TutorialSingleFetched.png" alt="screenshot" width="320px" />

## ListView

Let’s now modify this application to render all of this data in a ListView, rather than just the first movie.

First thing's first, add the ListView require to the top of the file.

```javascript
var {
AppRegistry,
Image,
ListView,
StyleSheet,
Text,
View,
} = React;
```

Now modify the render funtion so that once we have our data it renders a ListView of movies instead of a single movie.

```javascript
render: function() {
if (!this.state.loaded) {
return this.renderLoadingView();
}

return (
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderMovie}
/>
);
},
```

You'll notice we added a dataSource that comes from this.state. We'll now store the data there and then change this.state.movies === null to this.state.loaded === true to check if data has been loaded. Here's what getInitialState looks like:

```javascript
getInitialState: function() {
return {
dataSource: new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2,
}),
loaded: false,
};
},
```

And here's the modified this.setState in the response handler in fetchData:

```javascript
fetchData: function() {
fetch(REQUEST_URL)
.then((response) => response.json())
.then((responseData) => {
this.setState({
dataSource: this.state.dataSource.cloneWithRows(responseData.movies),
loaded: true,
});
})
.done();
},
```

Screenshot:

<img src="https://github.com/facebook/react-native/raw/master/docs/images/TutorialFinal.png" alt="screenshot" width="320px" />


### Final source code

```javascript
/**
* Sample React Native App
* https://github.com/facebook/react-native
*/
'use strict';

var React = require('react-native');
var {
AppRegistry,
Image,
ListView,
StyleSheet,
Text,
View,
} = React;

var API_KEY = '7waqfqbprs7pajbz28mqf6vz';
var API_URL = 'http://api.rottentomatoes.com/api/public/v1.0/lists/movies/in_theaters.json';
var PAGE_SIZE = 25;
var PARAMS = '?apikey=' + API_KEY + '&page_limit=' + PAGE_SIZE;
var REQUEST_URL = API_URL + PARAMS;

var SampleApp = React.createClass({
getInitialState: function() {
return {
dataSource: new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2,
}),
loaded: false,
};
},

componentDidMount: function() {
this.fetchData();
},

fetchData: function() {
fetch(REQUEST_URL)
.then((response) => response.json())
.then((responseData) => {
this.setState({
dataSource: this.state.dataSource.cloneWithRows(responseData.movies),
loaded: true,
});
})
.done();
},

render: function() {
if (!this.state.loaded) {
return this.renderLoadingView();
}

return (
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderMovie}
/>
);
},

renderLoadingView: function() {
return (
<View style={styles.container}>
<Text>
Loading movies...
</Text>
</View>
);
},

renderMovie: function(movie) {
return (
<View style={styles.container}>
<Image
source={{uri: movie.posters.thumbnail}}
style={styles.thumbnail}
/>
<View style={styles.rightContainer}>
<Text style={styles.title}>{movie.title}</Text>
<Text style={styles.year}>{movie.year}</Text>
</View>
</View>
);
},
});

var styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
rightContainer: {
flex: 1,
},
title: {
fontSize: 20,
marginBottom: 8,
textAlign: 'center',
},
year: {
textAlign: 'center',
},
thumbnail: {
width: 53,
height: 81,
},
});

AppRegistry.registerComponent('SampleApp', () => SampleApp);
```

Binary file added docs/images/TutorialFinal.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/TutorialMock.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/TutorialSingleFetched.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/TutorialStyledMock.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 12a7c2e

Please sign in to comment.