Categories
React Native

React Native — JavaScript Environment, Network, and Security

React Native is a mobile development that’s based on React that we can use to do mobile development.

In this article, we’ll look at how to use it to create an app with React Native.

JavaScript Environment

React Native runs in an environment that lets us use modern JavaScript features.

In most cases, React Native lets us run with JavaScriptCore, which also powers Safari.

We can use most modern features like for-of, object spread, template literals, spread and rest, modules, async and await, and more.

Also, we can use popular methods like console.log , array methods, object methods, and more.

Timers and InteractionManager

We can use the InteractionManager object to run timers on a separate thread.

This is better than the alternative of using JavaScript timer functions like setTimeout and setInterval in our React Native code.

For example, we can write:

InteractionManager.runAfterInteractions(() => {
  // ...long-running synchronous task...
});

We run runAfterInteractions method with a callback and we can run any long-running synchronous code in the callback.

Networking

We can make HTTP requests with the Fetch API in our React Native app.

For example, we can write:

import React, { useEffect, useState } from 'react';
import { View, StyleSheet, Text } from 'react-native';

export default function App() {
  const [answer, setAnswer] = useState('');

  const fetchData = async () => {
    const res = await fetch('https://yesno.wtf/api');
    const { answer } = await res.json();
    setAnswer(answer);
  }

  useEffect(() => {
    fetchData();
  }, [])

  return (
    <View style={styles.container}>
      <Text>{answer}</Text>
    </View >
  );
}

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

to make an HTTP request to an API.

We make a request when we load the app with the useEffect callback and an empty array for the 2nd argument.

WebSocket Support

React Native has WebSocket support.

To connect to a socket and listen to the connection, we can write:

const ws = new WebSocket('ws://host.com/path');

ws.onopen = () => {
  ws.send('something');
};

ws.onmessage = (e) => {
  console.log(e.data);
};

ws.onerror = (e) => {
  console.log(e.message);
};

ws.onclose = (e) => {
  console.log(e.code, e.reason);
};

The onopen method is run when we open the connection.

The onmessage method is run when a message is received.

onerror is run when an error occurred.

onclose method is run when the connection is closed.

Security

Like any other kind of apps, we’ve to think about security when we create our React Native app.

We should think about ways to store sensitive data.

To store environment variables, we can use the react-native-dotenv or react-native-config libraries.

We can use them to read things like API keys and other secrets from environment variables.

Secure Storage

To store data securely, we can use the Android Keystore to store items securely.

Also, we can use Encrypted Shared Preferences to store data.

Conclusion

We should think about security when we’re writing React Native apps.

Also, we can use the Fetch API to make HTTP requests from our React Native app.

Categories
React Native

React Native — Async Storage

React Native is a mobile development that’s based on React that we can use to do mobile development.

In this article, we’ll look at how to use it to create an app with React Native.

Async Storage

We can use the Async Storage library to store unencrypted data in our React Native app.

To install the library, we run:

yarn add @react-native-community/async-storage

Saving and Reading Data

Once we installed the library, we can import the library into our project and use it.

To do that, we write:

import React, { useState } from 'react';
import { View, StyleSheet, Text, Button } from 'react-native';
import AsyncStorage from '@react-native-community/async-storage';

export default function App() {
  const [data, setData] = useState();

const getData = async () => {
    try {
      const value = await AsyncStorage.getItem('@storage_Key')
      if (value !== null) {
        setData(value)
      }
    } catch (e) {
      // error reading value
    }
  }

  const storeData = async (value) => {
    try {
      await AsyncStorage.setItem('@storage_Key', value)
    } catch (e) {
      // saving error
    }
  }

  return (
    <View style={styles.container}>
      <Button title='save data' onPress={() => storeData('foo')}></Button>
      <Button title='read data' onPress={getData}></Button>
      <Text>{data}</Text>
    </View >
  );
}

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

We import the AsyncStorage object.

And we use them in the getData function to get data and the storeData function to store the data.

The AsyncStorage.getItem method gets the data by its key.

And AsyncStorage.setItem takes the key and the value for the key and save the data into storage.

We can also write and read objects as value.

For example, we can write:

import React, { useState } from 'react';
import { View, StyleSheet, Text, Button } from 'react-native';
import AsyncStorage from '@react-native-community/async-storage';

export default function App() {
  const [data, setData] = useState();

  const getData = async () => {
    try {
      const value = await AsyncStorage.getItem('@storage_Key')
      if (value !== null) {
        setData(JSON.parse(value))
      }
    } catch (e) {
      // error reading value
    }
  }

  const storeData = async () => {
    try {
      await AsyncStorage.setItem('@storage_Key', JSON.stringify({ foo: 'bar' }))
    } catch (e) {
      // saving error
    }
  }

  return (
    <View style={styles.container}>
      <Button title='save data' onPress={storeData}></Button>
      <Button title='read data' onPress={getData}></Button>
      <Text>{data.foo}</Text>
    </View >
  );
}

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

We called JSON.stringify to convert the object into a JSON string in storeData .

The getData function parses the stringified object that’s read from getItem with JSON.parse .

Remove Data

There’s also the removeItem method to remove data to remove an item by the key.

For example, we can write:

import React, { useState } from 'react';
import { View, StyleSheet, Text, Button } from 'react-native';
import AsyncStorage from '@react-native-community/async-storage';
export default function App() {
  const [data, setData] = useState();
  const getData = async () => {
    try {
      const value = await AsyncStorage.getItem('@storage_Key')
      setData(value);
    } catch (e) {
      // error reading value
    }
  }
  const storeData = async (value) => {
    try {
      await AsyncStorage.setItem('@storage_Key', value)
    } catch (e) {
      // saving error
    }
  }

  const removeValue = async () => {
    try {
      await AsyncStorage.removeItem('@storage_Key')
    } catch (e) {
      // remove error
    }
  }

  return (
    <View style={styles.container}>
      <Button title='save data' onPress={() => storeData('foo')}></Button>
      <Button title='read data' onPress={getData}></Button>
      <Button title='remove data' onPress={removeValue}></Button>
      <Text>{data}</Text>
    </View >
  );
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

We call removeItem with the key in the removeValue function to remove an item with the given key.

Conclusion

The async storage library gives us an easy way to store data in an unencrypted manner with React Native.

Categories
React Native

React Native — Accessibility Props and Performance Issues

React Native is a mobile development that’s based on React that we can use to do mobile development.

In this article, we’ll look at how to use it to create an app with React Native.

accessibilityValue

We can add the accessibilityValue prop to describe the component’s state.

Its value is an object that can have some properties:

  • min — min value of a component’s range
  • max— max value of a component’s range
  • now — current value of a component’s range
  • text — text description of the component’s value

min , max , and now are integers and text is a string.

importantForAccessibility

The importantForAccessibility prop is only available to Android apps.

It controls whether a view fires accessibility events and if it’s reported to accessibility services.

For example, we can write:

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

export default function App() {
  return (
    <View accessible={true} importantForAccessibility="yes" style={styles.container}>
      <Text>
        hello world
      </Text>
    </View>
  );
}

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

onAccessibilityTap

onAccessibilityTap prop takes a function that’s called when someone activates an accessible element by double-tapping.

Accessibility Actions

We can add accessibility actions that let assistive technology programmatically invoke the actions of a component.

A component must define a list of actions it supports via the accessbilityActions property.

And it must implement the onAccessbilityAction function to handle action requests.

For example, we can write:

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

export default function App() {
  return (
    <View
      accessible={true}
      accessibilityActions={[
        { name: 'cut', label: 'cut' },
        { name: 'copy', label: 'copy' },
        { name: 'paste', label: 'paste' }
      ]}
      onAccessibilityAction={(event) => {
        switch (event.nativeEvent.actionName) {
          case 'cut':
            Alert.alert('Alert', 'cut action success');
            break;
          case 'copy':
            Alert.alert('Alert', 'copy action success');
            break;
          case 'paste':
            Alert.alert('Alert', 'paste action success');
            break;
        }
      }}
      style={styles.container}
    >
      <Text>
        hello world
      </Text>
    </View>
  );
}

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

We add the props to our View so that we can show the alerts when those actions are executed.

Performance Problems

We should be careful when we’re creating our app.

One common source of slow performance is running our app in dev mode.

We should make sure we don’t do that with the production version.

Using console.log also slows down our app.

We should remove them as debugging.

When we want to use ListView s, we should replace them with FlatList or SectionList so that we get faster performance.

If we’re using ListView s, we should provide the rowHasChanged function checks whether the row has changed and needs to be re-rendered.

If we’re using touchable views, we won’t see any effect until the onPress function has returned.

If we set the state in the onPress function, then the touchable component may not look very responsive.

We can wrap our onPress actions in a requestAnimationFrame callback.

For example, we can write:

import React from 'react';
import { View, StyleSheet, TouchableNativeFeedback, Text } from 'react-native';
export default function App() {
  return (
    <View style={styles.container}>
      <TouchableNativeFeedback
        onPress={() => {
          requestAnimationFrame(() => {
            alert('You tapped the button!');
          });
        }}
      >
        <View style={styles.button}>
          <Text style={styles.buttonText}>TouchableNativeFeedback</Text>
        </View>
      </TouchableNativeFeedback>
    </View >
  );
}

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

to callrequestAnimationFrame in our onPress callback.

Conclusion

We can add accessibility props and fix common performance problems easily with React Native.

Categories
React Native

React Native — Accessibility

React Native is a mobile development that’s based on React that we can use to do mobile development.

In this article, we’ll look at how to use it to create an app with React Native.

Accessibility

We can add props to our components to make them accessible to assistive technologies.

For example, we can write:

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

export default function App() {
  return (
    <View accessible={true}>
      <Text>text one</Text>
      <Text>text two</Text>
    </View>
  );
}

We set the accessible prop to true to make the View accessible.

accessbilityLabel

Also, we can add an accessibilityLevel prop to our component to make it accessible.

For example, we can write:

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

export default function App() {
  return (
    <View accessible={true} style={styles.container}>
      <TouchableOpacity
        accessible={true}
        accessibilityLabel="Tap me!"
        onPress={() => alert('hello world')}>
        <View>
          <Text>Press me!</Text>
        </View>
      </TouchableOpacity>
    </View>
  );
}

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

to add a TouchableOpacity component that has the accessbilityLabel prop to help screen readers identify the button.

We can also add the accessibilityHint prop to add a hint for the user to understand what the button does.

For example, we can write:

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

export default function App() {
  return (
    <View accessible={true} style={styles.container}>
      <TouchableOpacity
        accessible={true}
        accessibilityLabel="Tap me!"
        accessibilityHint="Shows alert"
        onPress={() => alert('hello world')}>
        <View>
          <Text>Press me!</Text>
        </View>
      </TouchableOpacity>
    </View>
  );
}

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

accessibilityLiveRegion

The accessibilityLiveRegion prop is a prop that’s only available to Android apps.

It’s used to announce changes of the component to the user.

It can have 'none' , 'polite' and 'assertive' as the possible values.

'none' means don’t announce the changes.

'polite' means announce changes to the view.

'assertive' means interrupt ongoing speech to immediately announce changes to this view.

For example, we can write:

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

export default function App() {
  const [count, setCount] = React.useState(0);
  return (
    <View accessible={true} style={styles.container}>
      <TouchableWithoutFeedback onPress={() => setCount(c => c + 1)}>
        <View>
          <Text>Click me</Text>
        </View>
      </TouchableWithoutFeedback>
      <Text accessibilityLiveRegion="polite">
        Clicked {count} times
      </Text>
    </View>
  );
}

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

to add a Text component with the accessibilityLiveRegion prop to the Text component.

Now the changes to the text of this component will be announced.

accessibilityRole

The accessbilityRole prop lets us communicate what a component is used for to assistive technologies.

The list of possible values are at https://reactnative.dev/docs/accessibility#accessibilityrole.

accessibilityState

The accessibilityState prop describes the current state of a component to the user of assistive technologies.

It’s an object and it can have the disabled , selected , checked , busy , and expanded properties.

disabled indicates whether it’s disabled.

selected indicates whether it’s selected.

checked indicates whether it’s checked.

busy indicates whether it’s busy.

expanded indicates whether it’s expanded.

For instance, we can write:

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

export default function App() {
  return (
    <View accessible={true} style={styles.container}>
      <Text accessibilityState={{
        disabled: false,
        selected: false,
        checked: false,
        busy: false,
        expanded: false,
      }}>
        hello world
      </Text>
    </View>
  );
}

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

to set the values.

Conclusion

We can set the accessibility labels for components with React Native to make our app accessible.

Categories
React Native

React Native — Touchables and Navigation

React Native is a mobile development that’s based on React that we can use to do mobile development.

In this article, we’ll look at how to use it to create an app with React Native.

TouchableNativeFeedback

The TouchableNativeFeedback component is available on Android to let us display an ink service reaction when we touch it.

For example, we can write:

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

export default function App() {
  return (
    <View style={styles.container}>
      <TouchableNativeFeedback
        onPress={() => {
          alert('You tapped the button!');
        }}
      >
        <View style={styles.button}>
          <Text style={styles.buttonText}>TouchableNativeFeedback</Text>
        </View>
      </TouchableNativeFeedback>
    </View >
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  button: {
    marginBottom: 30,
    width: 260,
    alignItems: 'center',
    backgroundColor: '#2196F3'
  },
  buttonText: {
    textAlign: 'center',
    padding: 20,
    color: 'white'
  }
});

to add the TouchableNativeFeedback component with content inside.

TouchableOpacity

The TouchableOpacity component is used to provide feedback by reducing the opacity of the button.

The background will be seen through it while the user presses it down.

For instance, we can write:

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

export default function App() {
  return (
    <View style={styles.container}>
      <TouchableOpacity
        onPress={() => {
          alert('You tapped the button!');
        }}
      >
        <View style={styles.button}>
          <Text style={styles.buttonText}>TouchableOpacity </Text>
        </View>
      </TouchableOpacity >
    </View >
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  button: {
    marginBottom: 30,
    width: 260,
    alignItems: 'center',
    backgroundColor: '#2196F3'
  },
  buttonText: {
    textAlign: 'center',
    padding: 20,
    color: 'white'
  }
});

to add the TouchableOpacity component in our app.

TouchableWithoutFeedback

The TouchableWithoutFeedback component lets us add a touchable component without feedback.

For example, we can write:

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

export default function App() {
  return (
    <View style={styles.container}>
      <TouchableWithoutFeedback
        onPress={() => {
          alert('You tapped the button!');
        }}
      >
        <View style={styles.button}>
          <Text style={styles.buttonText}>TouchableWithoutFeedback </Text>
        </View>
      </TouchableWithoutFeedback >
    </View >
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  button: {
    marginBottom: 30,
    width: 260,
    alignItems: 'center',
    backgroundColor: '#2196F3'
  },
  buttonText: {
    textAlign: 'center',
    padding: 20,
    color: 'white'
  }
});

We add the TouchableWithoutFeedback component to add a button that doesn’t have any feedback when we touch it.

Navigating Between Screens

Mobile apps usually are made of multiple screens.

Therefore, we need a way to navigate between multiple screens.

React Native lets us do this with the React Navigation library.

To install the dependencies, we first run:

npm install @react-navigation/native @react-navigation/stack

Then we install the peer dependencies in our Expo manged project by running:

expo install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view

Then we can use the dependencies to add navigation by writing:

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { Button, StyleSheet, Text, View } from 'react-native';

const Stack = createStackNavigator();

const HomeScreen = ({ navigation }) => {
  return (
    <View style={styles.container}>
      <Text> Home</Text>
      <Button
        title="Go to Profile"
        onPress={() =>
          navigation.navigate('Profile', { name: 'Jane' })
        }
      />
    </View>
  )
}

const ProfileScreen = ({ navigation }) => {
  return (
    <View style={styles.container}>
      <Text>Profile</Text>
      <Button
        title="Go to Home"
        onPress={() =>
          navigation.navigate('Home')
        }
      />
    </View>
  )
}

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen
          name="Home"
          component={HomeScreen}
          options={{ title: 'Welcome' }}
        />
        <Stack.Screen name="Profile" component={ProfileScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

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

We have 2 components HomeScreen and Profile screen which are used for our app’s screens.

It has the navigation prop that lets us call the navigate method to navigate to the page we want.

In App , we add the NavigationContainer to add navigation.

Stack.Navigator is a container for the navigable components.

Stack.Screen adds our screens.

The component prop has the component to show.

Conclusion

We can add touchable components to add touchable items that has our own content.

Also, we can add navigation with various components.