This week we will create an app to visualize the React Native docs. It will have two screens: one screen listing all the docs and in the second, the content.

The idea is to open source this app and to have it as a model for future projects. This will be also a review of what we have studied so far. So if you’ve been following all the drips until now, this project should be easy for you.

If you find this project is pretty easy for you, try to think of ways to improve it! Remember, this project will be open source.

We will divide the episodes into:

  • Creating screens
  • Making the requests
  • Improving the layout

This episode will be about creating the screens and structuring the whole project.

We will have two screens: DetailsDocs and ListDocs.

  • ListDocs: The list of all the docs.
  • DetailsDocs: The content.

Here is the entry point of our application. We will use Navigator and create a function to render each scene.

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  Navigator,
  View
} from 'react-native';

import Main from './components/Main'
import DetailsDocs from './components/DetailsDocs/DetailsDocs'

function navigatorRenderScene(route, navigator) {
  switch (route.index) {
    case 'first':
      return (<Main navigator={navigator} title="Main Screen" />);
    case 'details':
      return (<DetailsDocs data={route.data} navigator={navigator} title="Details Docs" />);
  }
}

const reactNativeDocs = () => {
  return (<Navigator
        initialRoute={{ index: 'first' }}
        renderScene={navigatorRenderScene}
      />);
}

AppRegistry.registerComponent('reactNativeDocs', () => reactNativeDocs);

Let's create the Main. Our Main component is just a stateless component. It calls ListDocs and we pass the navigator.


const Main = (props) => {
  return (
    <View style={styles.container}>
      <View>
        <Text style={styles.main}>
          React Native Documentation
        </Text>
        <ListDocs navigator={props.navigator} />
      </View>
    </View>
  );
}

Let's create our DetailsDocs. It is a stateful component, where the state is content. Later we will change this state with content from the Github API. Right now, in the content, we will just pass content: 'Markdown from Github API'. As the contente is too long, we will have a scrollview for this.

import React, { Component } from 'react';
import {
  View,
  Text,
  StyleSheet,
  ScrollView
} from 'react-native';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    marginTop: 30,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
});

export default class DetailsDocs extends Component {
  constructor(props){
    super(props)
    this.state = {
      content: ''
    }
  }

    componentWillMount(){
      this.setState({
        content: 'Markdown from Github API'
      });
    }

    render(){
      return(
        <View style={styles.container}>
        <ScrollView>
          <Text>{ this.state.content }</Text>
        </ScrollView>
      </View>
      )
    }
}

Nice! So far, we have created the DetailsScreen, but we should create the list of all content. Let's create a ListDocs. To be quick, let's just copy DetailDocs and change the file.

This screen is very common, it will be just a listview, we already did it before. So, it should be familiar to you.

In the componentWillMount we will update the state with some fake data. And the initial State we will just put 'Loading...'. The idea is get the data from a API call inside the componentWillMount.

import React, { Component } from 'react';
import {
  StyleSheet,
  Text,
  ListView,
  Image,
  TouchableHighlight,
  View
} from 'react-native';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  textComponent: {
    fontSize: 24,
  }
});

export default class ListDocs extends Component {
  constructor(props){
    super(props)
    this.ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
    this.state = {
      dataSource: this.ds.cloneWithRows([
        'Loading...'
      ])
    }

    this.onClickList = this.onClickList.bind(this)

  }

  onClickList(rowData){
    this.props.navigator.push({
      index: 'details',
      data: rowData
    })
  }

  componentWillMount(){
      var listFromGithub = ['Colors', 'Animation', 'Images', 'InputText']
      this.setState({
        dataSource: this.ds.cloneWithRows(listFromGithub)
      })
    }

    render(){

      return(
        <View style={styles.container}>
        <View>
          <ListView
            dataSource={this.state.dataSource}
            renderRow={(rowData) =>
              <TouchableHighlight underlayColor='white' onPress={this.onClickList.bind(this, rowData)}>
              <View>
                <Text style={styles.textComponent}>{rowData}</Text>
              </View>
              </TouchableHighlight>
            }
          />
        </View>
      </View>
      )
    }
}

We just have a notion on how our app will be. With this, the screen of our application are done. We will see how we are handling the github calls and rendering the markdown from the documentation.