My Jump from React to React Native

Daniel Hahm
3 min readOct 6, 2020

--

I have recently created my first React Native application using Rails as the backend. Here is a quick demo of my app FitCo.

Demo 1

Major differences between React & React Native

  1. Routes replaced with navigation.
  2. DOM events such as: event.target will not work in RN. (See more here.)
  3. HTML is deprecated in RN. No more <html> tags of any sort.
  4. Handling events onClick to onPress.
  5. List an array of objects within a component requires FlatList.
  6. LocalStorage to AsyncStorage.
  7. CSS to RN Stylesheet.

Navigation

Navigation is the biggest change coming from a web application to mobile. At first it can be confusing deciding when to use a stack navigator, tab navigator, or draw navigator when connecting one to another. When creating your wireframes I recommend drawing out a tree structure to visualize the navigation.

For my app, I wanted two different user experiences. One for the instructors and the other for students. They both have different stack & tab navigations:

Note: Auth not included in this example

As shown above, there are two tab navigators, each with its own list of screens or nested stack navigators. Planning out each navigation prior to starting a project will help organize your source code.

Please refer to this link: https://reactnavigation.org/ for examples and more information on navigation types. Installation and imports are also required.

example Stack Navigator
example Tab Navigator (using Ionicons for Icons)

Event Handling

Event handling is different on mobile. React Native comes with gestures, button press, scroll view, etc. Thus, a property that is commonly used is onPress or onChangeText.

                <FontAwesome 
name="id-badge"
size={20}
/>
<TextInput
style={styles.textInput}
value={this.state.username}
placeholder="Username"
placeholderTextColor='#A9A9A9'
type='username'
onChangeText={this.changeHandler("username")}
/>
... changeHandler = (name) => (text) => {
this.setState({ [name]: text});
}

Example of onPress below:

<Text style={styles.text_account}>Select Account</Text>
<View style={styles.buttons}>
<CheckBox
center
iconRight
title='Coach'
checked={this.state.flag}
onPress={() => {this.setState({flag: true})}}
/>
<CheckBox
center
iconRight
title='Student'
checked={!this.state.flag}
onPress={() => {this.setState({flag: false})}}
/>
</View>

FlatList

Since HTML is not supported in React Native, FlatList is a workaround.

          <FlatList
data={comments}
keyExtractor={item => `${item.key}`}
renderItem={({ item }) => <Comment {...item} />}
ItemSeparatorComponent={this.renderSeparator}
/>

Common Issues:
"VirtualizedList: missing keys for items, make sure to specify a key property on an item or provide a custom keyExtractor"

Make sure to set the KeyExtractor.
keyExtractor={(item, index) => item.key}

More on FlatList: https://reactnative.dev/docs/flatlist.html

AsyncStorage

Instead of using localStorage, React Native comes with AsyncStorage. This comes in handy when checking for the current user’s token.

More info here: https://reactnative.dev/docs/asyncstorage

Other Useful Tools In React Native

ScrollView from ‘react-native’

A wrapper works wonders with horizontal scrolling. As shown in the demo earlier for Trending Posts & Trending Coaches.

            <ScrollView> 
<Animatable.View
delay={1200}
animation="fadeInLeft"
duraton="9000">
<ImageBackground
source={require('../assets/images/homescreen.png')}
style={{width: '100%', height: 270}}
imageStyle={{borderBottomRightRadius:65}}>
<View style={styles.searchContainer}>
<Text style={styles.userGreet}>
Welcome to FitCo</Text>
<Text style={styles.userText}>
Check out the lastest Posts and featured Coaches</Text>
</View>
</ImageBackground>
</Animatable.View>
<ScrollView>

More info here: https://reactnative.dev/docs/scrollview

TouchableOpacity from ‘react-native’

A wrapper for responsive touch to your views, text, button, etc.

           <TouchableOpacity 
style={styles.button3}
onPress={() => onPressLeft()}>
<Text style={styles.dislike}>
<FontAwesome name="times-circle"
size={65}
style={{color: '#DC143C'}}/>
</Text>
</TouchableOpacity>

Dimensions from ‘react-native’

Useful for setting default width/height when applying flex-box, stylesheets, etc.
const fullWidth = Dimensions.get('window').width;

Additionally, look into PixelRatio: https://reactnative.dev/docs/pixelratio

ActivityIndicator from ‘react-native’

Used for loading screen and transitioning from one screen to another.

{this.props.follows.isLoading ?
<ActivityIndicator size="small"/>
:
// ... render screen
}

StyleSheet from ‘react-native’

Styling is straightforward and only requires a simple import.

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
...

Recommendation

Applying Redux and/or React Hooks to your application will help manage state from one screen to another without having to worry about passing props around.

Take advantage of component lifecycle if you require a re-render. ComponentDidMount & ComponentDidUpdate comes in handy in most cases.

Useful Libraries Used In My Application

General:

react-redux

redux-thunk

react-native-popup-dialog

react-navigation

react-native-nodemediaclient

react-native-video

react-native-image-picker

Styling:

reanimated-bottom-sheet

react-native-card-stack-swiper

react-native-animatable

react-native-vector-icons (materialIcon, fontAwesome, Ionicons)

Dev tools:

remote-redux-devtools

react-devtools

As always, thank you for reading!

--

--