5 lessons learned on Keytrade Bank’s React Native project

5 lessons learned on Keytrade Bank’s React Native project

Keytrade React Native

In last year’s business case about Keytrade’s future-proof online banking and trading platform, we put forward React Native as the next step in developing the mobile app version. A year ago, icapps ran a PoC to determine whether React Native was the way to go. Even though the React Native technology was still in its infancy back then, we believed it would be a time- and money-saver. A few months later, React Native has proved its worth: maximum code reuse, live reload (enabling you to immediately see the result of the latest change that you have made to the code), modular and intuitive architecture and it’s superfast.

In the case of the Keytrade Bank project, two native apps (Android & iOS) were built over a 6-month period. Inconsistencies between iOS and Android disappeared and maintenance was much more simplified. Thanks to the React Native app, Keytrade Bank is ready to unify the workflow between its different teams, since they can use features covering backend, web and app at the same time.

The Keytrade Bank app is the first banking app built with React Native in Belgium. As pioneers, we learned a lot. Let’s highlight 5 lessons we’ve learned on the Keytrade Bank project.

1. Collect generic components

At the beginning of the project, go through the requirements and designs and make a list of generic or recurring components. After creating a few items, we quickly realised we could combine most of the items into 1 generic component.

Once you do that, and you talk to the product owner (PO) and designer to keep the designs in sync with the components you already have, you can create views faster than ever.

Another example is every Text field in the app. When we started we wrote something like this for every text :

  <Text style={styles.header}>This is the header</Text>
  <Text style={styles.content}>This is the content</Text>
 
  const styles = StyleSheet.create({
    header: {
      fontFamily: 'OpenSans-Bold',
      color: colors.primary_blue,
      fontSize: 24,
      lineHeight: 32,
    },
    content: {
      fontFamily: 'OpenSans-regular',
      color: colors.text,
      fontSize: 12,
      lineHeight: 16,
    },
  });

But doing this for every textfield is a very repetitive job, so we created a generic text component:

   import { Text as RNText } from 'react-native'
  import { colors } from '../../utils'
 
  export const Text = ({style, label, uppercase, ...props}) => {
    const styles = [getFontFamily(props), getFontColor(props), getFontSize(props), style]
    return <RNText style={styles} {...props} />
  }
 
  const getFontFamily = (props) => {
    let fontFamily = 'OpenSans-regular'
    if (props.bold) fontFamily = 'OpenSans-Bold'
    return {fontFamily}
  }
 
  const getFontColor = (props) => {
    let color = colors.text
    if (props.white) color = colors.white
    if (props.primaryBlue) color = colors.primary_blue
    return {color}
  }
 
  const getFontSize = (props) => {
    let fontSize = 12
    let lineHeight = 16
    if (props.small) { fontSize = 12; lineHeight = 16 }
    if (props.xlarge) { fontSize = 24; lineHeight = 32 }
    return {fontSize: fontSize, lineHeight: lineHeight}
  }

Which allows us to write:

  <Text bold xlarge primaryBlue>This is the header</Text>
  <Text>This is the content</Text>

...to get the same result.

2. Do not fear animations…

… but don't over-animate your app.

Animations can give your app just the extra touch. We used a combination of Lottie animations (a mobile library for Android and iOS), the RN Animated library and the react-native-animatable package.

Those allowed us to integrate some snappy animations without a lot of effort.

React Native Keytrade AnnimationsReact Native Keytrade Annimations

 

3. Make your redux store immutable

We used immutableJS for our redux store to prevent side-effects and wrong rerenders in our app. Without immutability we could sometimes change our store in a way that we got poor results in our app (data was already updated and didn't trigger correct react rerenders).

The immutability forced us to use selectors and made it possible to integrate reselect in our app.

It also forced us to re-think some redux structures and do optimisations to our store.

4. Set up continuous integration

Set up continuous integration from the beginning of the project, so you can provide alpha and beta build to the rest of the team.

Under normal circumstances, apps developed by icapps get built within a continuous integration environment. Because the development of this project started within Keytrade Bank, such a CI pipeline was not completely available from the start. So we helped Keytrade Bank to improve it and to make it more efficient.

5. Find a good trade-off between platform specific and generic code / design.

At icapps we strive for perfection. It's the small things like a ripple on a button for Android, the default pull-to-refresh spinners, a back chevron on iOS and a back arrow on Android that give an app just the finishing touch.

On the other hand, in the case of React Native it’s sometimes beneficial / deliberated to make a trade-off between designs and choose the option that works well for both iOS and Android.

Small tip: you can use platform-specific images. If you suffix them with the specific platform, RN will take the correct image.

For example:

search.ios.png

search.android.png

search@2x.ios.png    

search@2x.android.png

search@3x.ios.png    

search@3x.android.png

Search navigation bar and tab bar icon


 

Interested in learning more about React Native? Read our blogs: 5 key advantages of React Native , What is the right background for a React Native developer? and React Native: a brief history.