Fixed navigation template

Summary:
- [x] Explain the **motivation** for making this change.

It fixes #14313
Closes https://github.com/facebook/react-native/pull/14495

Differential Revision: D6042094

Pulled By: hramos

fbshipit-source-id: d70e42bfee0a22882bad91cb885fb0cfc91c7d38
This commit is contained in:
alejandro garcia 2017-10-12 11:32:30 -07:00 committed by Facebook Github Bot
parent f2c6877b91
commit 224d29447f
9 changed files with 47 additions and 73 deletions

View File

@ -1,5 +1,3 @@
'use strict';
/**
* This is an example React Native app demonstrates ListViews, text input and
* navigation between a few screens.

View File

@ -1,6 +1,6 @@
# App template for new React Native apps
This is a simple React Native app template which demonstrates a few basics concepts such as navigation between a few screens, ListViews, and handling text input.
This is a simple React Native app template which demonstrates a few basics concepts such as navigation between a few screens, FlatLists, and handling text input.
<img src="https://cloud.githubusercontent.com/assets/346214/22697898/ced66f52-ed4a-11e6-9b90-df6daef43199.gif" alt="Android Example" height="800" style="float: left"/>
@ -13,7 +13,7 @@ The idea is to make it easier for people to get started with React Native. Curre
- Navigating between screens
- Handling text input and the software keyboard
This app serves as a template used by `react-native init` so it is easier for anyone to get up and running quickly by having an app with a few screens and a ListView ready to go.
This app serves as a template used by `react-native init` so it is easier for anyone to get up and running quickly by having an app with a few screens and a FlatList ready to go.
### Best practices
@ -21,7 +21,7 @@ Another purpose of this app is to define best practices such as the folder struc
## Not using Redux
This template intentionally doesn't use Redux. After discussing with a few people who have experience using Redux we concluded that adding Redux to this app targeted at beginners would make the code more confusing, and wouldn't clearly show the benefits of Redux (because the app is too small). There are already a few concepts to grasp - the React component lifecycle, rendeing lists, using async / await, handling the software keyboard. We thought that's the maximum amount of things to learn at once. It's better for everyone to see patterns in their codebase as the app grows and decide for themselves whether and when they need Redux. See also the post [You Might Not Need Redux](https://medium.com/@dan_abramov/you-might-not-need-redux-be46360cf367#.f3q7kq4b3) by [Dan Abramov](https://twitter.com/dan_abramov).
This template intentionally doesn't use Redux. After discussing with a few people who have experience using Redux we concluded that adding Redux to this app targeted at beginners would make the code more confusing, and wouldn't clearly show the benefits of Redux (because the app is too small). There are already a few concepts to grasp - the React component lifecycle, rendering lists, using async / await, handling the software keyboard. We thought that's the maximum amount of things to learn at once. It's better for everyone to see patterns in their codebase as the app grows and decide for themselves whether and when they need Redux. See also the post [You Might Not Need Redux](https://medium.com/@dan_abramov/you-might-not-need-redux-be46360cf367#.f3q7kq4b3) by [Dan Abramov](https://twitter.com/dan_abramov).
## Not using Flow (for now)
@ -34,7 +34,7 @@ We need your feedback. Do you have a lot of experience building React Native app
## How to use the template
```
$ react-native init MyApp --version 0.42.0-rc.2 --template navigation
$ react-native init MyApp --template navigation
$ cd MyApp
$ react-native run-android
$ react-native run-ios

View File

@ -1,3 +1,3 @@
{
"react-navigation": "1.0.0-beta.5"
"react-navigation": "1.0.0-beta.11"
}

View File

@ -1,5 +1,3 @@
'use strict';
import { TabNavigator } from 'react-navigation';
import ChatListScreen from './chat/ChatListScreen';

View File

@ -1,10 +1,8 @@
'use strict';
import React, { Component } from 'react';
import {
ActivityIndicator,
Image,
ListView,
FlatList,
Platform,
StyleSheet,
View,
@ -16,47 +14,41 @@ export default class ChatListScreen extends Component {
static navigationOptions = {
title: 'Chats',
header: {
visible: Platform.OS === 'ios',
},
tabBar: {
icon: ({ tintColor }) => (
<Image
// Using react-native-vector-icons works here too
source={require('./chat-icon.png')}
style={[styles.icon, {tintColor: tintColor}]}
/>
),
},
header: Platform.OS === 'ios' ? undefined : null,
tabBarIcon: ({ tintColor }) => (
<Image
// Using react-native-vector-icons works here too
source={require('./chat-icon.png')}
style={[styles.icon, {tintColor: tintColor}]}
/>
),
}
constructor(props) {
super(props);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
isLoading: true,
dataSource: ds,
};
}
async componentDidMount() {
const chatList = await Backend.fetchChatList();
this.setState((prevState) => ({
dataSource: prevState.dataSource.cloneWithRows(chatList),
chatList,
isLoading: false,
}));
}
// Binding the function so it can be passed to ListView below
// and 'this' works properly inside renderRow
renderRow = (name) => {
// Binding the function so it can be passed to FlatList below
// and 'this' works properly inside renderItem
renderItem = ({ item }) => {
return (
<ListItem
label={name}
label={item}
onPress={() => {
// Start fetching in parallel with animating
this.props.navigation.navigate('Chat', {
name: name,
name: item,
});
}}
/>
@ -72,9 +64,10 @@ export default class ChatListScreen extends Component {
);
}
return (
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderRow}
<FlatList
data={this.state.chatList}
renderItem={this.renderItem}
keyExtractor={(item, index) => index}
style={styles.listView}
/>
);

View File

@ -1,10 +1,8 @@
'use strict';
import React, { Component } from 'react';
import {
ActivityIndicator,
Button,
ListView,
FlatList,
StyleSheet,
Text,
TextInput,
@ -15,16 +13,13 @@ import Backend from '../../lib/Backend';
export default class ChatScreen extends Component {
static navigationOptions = {
title: (navigation) => `Chat with ${navigation.state.params.name}`,
}
static navigationOptions = ({ navigation }) => ({
title: `Chat with ${navigation.state.params.name}`,
});
constructor(props) {
super(props);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
messages: [],
dataSource: ds,
myMessage: '',
isLoading: true,
};
@ -47,7 +42,6 @@ export default class ChatScreen extends Component {
}
this.setState((prevState) => ({
messages: chat.messages,
dataSource: prevState.dataSource.cloneWithRows(chat.messages),
isLoading: false,
}));
}
@ -82,7 +76,6 @@ export default class ChatScreen extends Component {
];
return {
messages: messages,
dataSource: prevState.dataSource.cloneWithRows(messages),
myMessage: '',
};
});
@ -93,10 +86,10 @@ export default class ChatScreen extends Component {
this.setState({myMessage: event.nativeEvent.text});
}
renderRow = (message) => (
renderItem = ({ item }) => (
<View style={styles.bubble}>
<Text style={styles.name}>{message.name}</Text>
<Text>{message.text}</Text>
<Text style={styles.name}>{item.name}</Text>
<Text>{item.text}</Text>
</View>
)
@ -110,12 +103,13 @@ export default class ChatScreen extends Component {
}
return (
<View style={styles.container}>
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderRow}
style={styles.listView}
onLayout={this.scrollToBottom}
/>
<FlatList
data={this.state.messages}
renderItem={this.renderItem}
keyExtractor={(item, index) => index}
style={styles.listView}
/>
<View style={styles.composer}>
<TextInput
ref={(textInput) => { this.textInput = textInput; }}

View File

@ -1,5 +1,3 @@
'use strict';
import React, { Component } from 'react';
import {
Image,
@ -14,18 +12,15 @@ export default class WelcomeScreen extends Component {
static navigationOptions = {
title: 'Welcome',
header: {
visible: Platform.OS === 'ios',
},
tabBar: {
icon: ({ tintColor }) => (
<Image
// Using react-native-vector-icons works here too
source={require('./welcome-icon.png')}
style={[styles.icon, {tintColor: tintColor}]}
/>
),
},
// You can now set header: null on any component to hide the header
header: Platform.OS === 'ios' ? undefined : null,
tabBarIcon: ({ tintColor }) => (
<Image
// Using react-native-vector-icons works here too
source={require('./welcome-icon.png')}
style={[styles.icon, {tintColor: tintColor}]}
/>
),
}
render() {

View File

@ -1,5 +1,3 @@
'use strict';
import React, { Component } from 'react';
import {
StyleSheet,

View File

@ -1,5 +1,3 @@
'use strict';
import React, { Component } from 'react';
import {
StyleSheet,