Categories
React Native

React Native — Images, Views, and Text

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 Reac.

Uri Data Images

We can add images for a base64 URI.

For example, we can write:

import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { Image, StyleSheet, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <Image
        style={{
          width: 51,
          height: 51,
          resizeMode: 'contain'
        }}
        source={{
          uri:
            'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAzCAYAAAA6oTAqAAAAEXRFWHRTb2Z0d2FyZQBwbmdjcnVzaEB1SfMAAABQSURBVGje7dSxCQBACARB+2/ab8BEeQNhFi6WSYzYLYudDQYGBgYGBgYGBgYGBgYGBgZmcvDqYGBgmhivGQYGBgYGBgYGBgYGBgYGBgbmQw+P/eMrC5UTVAAAAABJRU5ErkJggg=='
        }}
      />
      <StatusBar style="auto" />
    </View>
  );
}

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

We just set the uri property to set the image URI.

We should only use this for small images.

Background Image

For example, we can write:

import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { ImageBackground, StyleSheet, View, Text } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <ImageBackground source={require('./assets/fork.jpg')} style={{ width: '100%', height: '100%' }}>
        <Text>Inside</Text>
      </ImageBackground>
      <StatusBar style="auto" />
    </View>
  );
}

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

We used the ImageBackground component to add the background image.

Then we can have things like text inside it.

View

A View is a container that supports layouts with flexbox, styles, touch handling, and accessibility controls.

For example, we can write:

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

export default function App() {
  return (
    <View
      style={{
        flexDirection: "row",
        height: 100,
        padding: 20
      }}
    >
      <View style={{ backgroundColor: "green", flex: 0.3 }} />
      <View style={{ backgroundColor: "red", flex: 0.5 }} />
      <Text>Hello World!</Text>
    </View>
  );
}

The outer View component is a flexbox container for the inner View components.

We can set the backgroundColor for views.

And we can add the Text component to add the text.

Text

The Text component is a component that’s used for displaying text.

For example, we can write:

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

const onPressTitle = () => {
  console.log("title pressed");
};

export default function App() {
  const titleText = useState("Bird's Nest");
  const bodyText = useState("This is not really a bird nest.");

  return (
    <View
      style={{
        flexDirection: "row",
        height: 100,
        padding: 20
      }}
    >
      <Text style={styles.baseText}>
        <Text style={styles.titleText} onPress={onPressTitle}>
          {titleText}
          {"n"}
        </Text>
        <Text numberOfLines={5}>{bodyText}</Text>
      </Text>
    </View>
  );
}

const styles = StyleSheet.create({
  baseText: {
    fontFamily: "Cochin"
  },
  titleText: {
    fontSize: 20,
    fontWeight: "bold"
  }
});

We can add the Text component to add some text.

We add the onPress prop and pass in an event handler to add an event handling for touching the text.

Conclusion

We can add URIs for images and background images with React Native.

Also, we can add View components for containers and Text component for text.

Categories
React Native

React Native — Flat Lists

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.

FlatList

We can add the FlatList component to display a simple list view.

It’s cross-platform and works with horizontal mode.

Also, it has header, footer, and separator support.

We can pull it to refresh the data.

We can load data as we scroll with it.

And it also has multiple columns support.

For example, we can write:

import React from 'react';
import { SafeAreaView, FlatList, StyleSheet, View, Text } from 'react-native';
const DATA = Array(100).fill().map((_, i) => ({ id: i, title: i }))

const Item = ({ title }) => (
  <View style={styles.item}>
    <Text style={styles.title}>{title}</Text>
  </View>
);

const renderItem = ({ item }) => (
  <Item title={item.title} />
);

export default function App() {
  return (
    <SafeAreaView style={styles.container}>
      <FlatList
        data={DATA}
        renderItem={renderItem}
        keyExtractor={item => item.id}
      />
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    marginTop: 0
  },
  item: {
    backgroundColor: '#f9c2ff',
    padding: 20,
    marginVertical: 8,
    marginHorizontal: 16,
  },
  title: {
    fontSize: 32,
  },
});

to create our list.

We create the Item component that renders the View and Text component for a list item.

The renderItem function is a function to render a Item .

Then we add a SafeAreaView and a FlatList to let us render a scrollable list.

We pass an array in the data prop.

And the renderItem prop has the renderItem function we created earlier.

keyExtractor is a function to get the unique key for an item.

We can make our items selectable by using the TouchableOpacity component:

import React from 'react';
import { SafeAreaView, FlatList, StyleSheet, Text, TouchableOpacity } from 'react-native';
const DATA = Array(100).fill().map((_, i) => ({ id: i, title: i }))

const Item = ({ item: { title }, onPress, style }) => (
  <TouchableOpacity onPress={onPress} style={[styles.item, style]}>
    <Text style={styles.title}>{title}</Text>
  </TouchableOpacity>
);

export default function App() {
  const [selectedId, setSelectedId] = React.useState(null);
  const renderItem = ({ item }) => {
    const backgroundColor = item.id === selectedId ? "lightgreen" : "pink";
    return (
      <Item
        item={item}
        onPress={() => setSelectedId(item.id)}
        style={{ backgroundColor }}
      />
    );
  };

return (
    <SafeAreaView style={styles.container}>
      <FlatList
        data={DATA}
        renderItem={renderItem}
        keyExtractor={item => item.id}
        extraData={selectedId}
      />
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    marginTop: 0
  },
  item: {
    backgroundColor: '#f9c2ff',
    padding: 20,
    marginVertical: 8,
    marginHorizontal: 16,
  },
  title: {
    fontSize: 32,
  },
});

The Item component is rendered with the TouchableOpacity component to let us show something different when it’s selected.

In the App component, we have the renderItem function which takes the item and set the background color according to which one is pressed.

We determine which one is pressed with the onPress prop, which takes a function that calls setSelectedId to set the selected item’s ID.

Then in the style prop, we set the backgroundColor property to the color we want according to whether the selectedId is the same as the current item’s id .

Now when an item is selected, the item has a lightgreen background.

Otherwise, it has a pink background.

Conclusion

We can add a FlatList component to display a scrollable list of items.

Categories
React Native

Getting Started with Mobile Development with React Native

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 our first app.

Getting Started

To get started with React Native, we’ve to install the Expo CLI.

We run:

npm install -g expo-cli

to install it.

Node 12 LTS or later is required.

Then we can create a React Native project by writing:

expo init react-native-example

We also have to install Android SDK with an Android device or emulator.

We can install Genymotion which is faster than the Android emulator.

To install it, we can go to https://www.genymotion.com/ to download it.

Then we go to:

cd react-native-example
yarn android

to start the Expo CLI.

In the react-native-example project, we have App.js which has:

import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <Text>Open up App.js to start working on your app!</Text>
      <StatusBar style="auto" />
    </View>
  );
}

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

The View component has the main app view.

The Text component has text.

StatusCar has the status bar.

The StyleSheet.create method creates the styles.

Then we applied it with the styles prop.

We can use flexbox and other CSS properties for our layouts.

Images

We can add images by using the Image component.

For example, we can write:

import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { Image, StyleSheet, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <Image source={require('./assets/fork.jpg')} />
      <StatusBar style="auto" />
    </View>
  );
}

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

We add the Image component with the source prop to set the image.

We can also add icons from a URL. For example, we can write:

import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { Image, StyleSheet, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <Image source={{ uri: 'https://reactjs.org/logo-og.png' }}
        style={{ width: 400, height: 400 }} />
      <StatusBar style="auto" />
    </View>
  );
}

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

We can also set other HTML request data like the headers and body when we get the image.

For example, we can write:

import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { Image, StyleSheet, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <Image
        source={{
          uri: 'https://reactjs.org/logo-og.png',
          method: 'POST',
          headers: {
            Pragma: 'no-cache'
          },
          body: 'Your Body goes here'
        }}
        style={{ width: 400, height: 400 }}
      />
      <StatusBar style="auto" />
    </View>
  );
}

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

Conclusion

We can get started with mobile development with React Native in a few minutes.

And we can use Genymotion or a real device to preview our app fast.

Categories
Redux

Intro to React State Management with React-Redux

React is a library for creating front end views. It has a big ecosystem of libraries that work with it. Also, we can use it to enhance existing apps.

To store data in a central place for easy accessibility by components, we have to use some state management solutions. React-Redux is a popular choice.

In this article, we’ll look at how to add it to our React app and simple use cases.

Installation

To install the react-redux package, we have install react-redux and its dependency redux .

We can install both by running:

npm install react-redux redux

with NPM or if we use Yarn:

yarn add react-redux redux

Set Up a Redux Store

After installing both packages, we have to set up our Redux store to hold our data.

To do this we write:

import { createStore } from "redux";

function counterReducer(state = 0, action) {
  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    default:
      return state;
  }
}

const store = createStore(counterReducer);

The code above creates a Redux store by creating the counterReducer reducer function.

The reducer specifies how the app’s state changes in response to actions sent to the store.

Our counterReducer only accepts one action, which is 'INCREMENT' . We respond to the action by returning the state and adding 1 to it.

There’s also a default case to just return the state value as is.

Then we create a store by calling Redux’s createStore function and passing in our reducer.

It returns the store , which we can pass into our React app.

Connecting the Store to our React App

This is where we need the functions of React-Redux.

We can connect the store to our app so we can store our app’s state in the store by using React-Redux’s connect function.

connect takes 2 functions, which are mapStateToProps and mapDispatchToProps . They’re the first and second argument respectively.

First, we can put the whole app together by connecting our store with the React app as follows:

import React from "react";
import { Provider, connect } from "react-redux";
import { createStore } from "redux";
import ReactDOM from "react-dom";

function counterReducer(state = 0, action) {
  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    default:
      return state;
  }
}

const store = createStore(counterReducer);

class App extends React.Component {
  onClick() {
    this.props.increment();
  }
  render() {
    const { count } = this.props;
    return (
      <>
        <button onClick={this.onClick.bind(this)}>Increment</button>
        <p>{count}</p>
      </>
    );
  }
}

const mapDispatchToProps = dispatch => {
  return {
    increment: () => dispatch({ type: "INCREMENT" })
  };
};
const mapStateToProps = state => ({
  count: state
});

App = connect(
  mapStateToProps,
  mapDispatchToProps
)(App);
const rootElement = document.getElementById("root");
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  rootElement
);

In the code, we have an app that shows a number going up as we click the Increment button.

The first step to connect the store to our React app is to wrap the Provider component around our whole app.

To do this we, wrote the following:

<Provider store={store}>
  <App />
</Provider>

Then we define the mapStateToProps and mapDispatchToProps functions as follows:

const mapDispatchToProps = dispatch => {
  return {
    increment: () => dispatch({ type: "INCREMENT" })
  };
};
const mapStateToProps = state => ({
  count: state
});

In mapStateToProps we return a object to map the state object to a React component prop name as indicated in the property name. The state is the state stored in the Redux store.

So we mapped state to the prop count .

In mapDispatchToProps , we get the dispatch parameter, which is a function used to dispatch our action to the store, and return an object with the name for the function we can access from the props to call and dispatch the action.

So in mapDispatchToProps , increment is our function name. We can call it by running this.props.increment in our App component.

increment is a function that runs dispatch({ type: “INCREMENT” }) .

Then in our App component, we define the onClick method to call this.props.increment to dispatch the ‘INCREMENT’ action to our counterReducer via our Redux store and increase the state by 1.

Then since we have mapStateToProps , the latest value is being observed by App and the latest value is available via this.state.count as indicated in mapStateToProps .

Then when we click the Increment button, we’ll get the number going up by 1.

This will happen with every click.

Conclusion

We can use Redux in our React app by creating a store.

Next, we use the React-Redux Provider component and wrap it around our App entry-point component. We pass our Redux store to the store prop so that we can map the state and dispatch actions to props.

Then connecting it to our store via React Redux’s connect function. We pass in the mapStateToProps and mapDispatchToProps to map the store’s state to our component’s props and map our dispatch function call to our props respectively.

Categories
Redux

Using the React-Redux useSelector Hook

With Redux, we can use it to store data in a central location in our JavaScript app. It can work alone and it’s also a popular state management solution for React apps when combined with React-Redux.

In this article, we’ll look at the new hooks React-Redux Hooks API.

Using the useSelector Hook in a React Redux App

The hooks API consists of the useSelector , useDispatch , and useStore hooks.

The useSelector hook takes a selector function to select data from the store and another function equalityFn to compare them before returning the results and determine when to render if the data from the previous and current state are different.

The call takes the following format:

const result : any = useSelector(selector : Function, equalityFn? : Function)

It’s equivalent to mapStateToProps in connect. The selector will be called with the entire Redux store state as its only argument.

The selector function may return any value as a result, not just an object. The return value of the selector will be used as the return value of the useSelector hook.

When an action is dispatched, useSelector will do a shallow comparison of the previous selector result value and the current one.

The selector function doesn’t receive an ownProps argument. Props can be used through closure or by using the curried selector.

We may call useSelector multiple times within a single function component. Each call creates an individual subscription to the Redux store. React update batching behavior will cause multiple useSelector s in the same component to return new value should only return in a single re-render.

Equality Comparisons and Updates

The provided selector function will be called and its result will be returned from the useSelector hook. A cached result may be returned if the selector is run and returns the same result.

useSelector only forces a re-render if the selector result appears to be different than the last result.

This is different from connect , which uses shallow equality checks on the results of mapState calls to determine if re-rendering is needed.

If we want to retrieve multiple values from the store, we can call useSelector multiple times with each call returning a single field value, use Reselect or a similar library to create a memoized selector that returns multiple values in an object but returns a new object when one of the values is changed.

We can also use the shallowEqual function from React-Redux as the equalityFn argument to useSelector .

For example, we can use useSelector as follows:

import React from "react";
import ReactDOM from "react-dom";
import { Provider, useSelector, useDispatch } from "react-redux";
import { createStore } from "redux";
function count(state = 0, action) {
  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    case "DECREMENT":
      return state - 1;
    default:
      return state;
  }
}

const store = createStore(count);

function App() {
  const count = useSelector(state => state);
  const dispatch = useDispatch();

  return (
    <div className="App">
      <button onClick={() => dispatch({ type: "INCREMENT" })}>Increment</button>
      <button onClick={() => dispatch({ type: "DECREMENT" })}>Decrement</button>
      <p>{count}</p>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  rootElement
);

In the code above, we created the store as usual. Then in the App component, we used the useSelector hook to get the count by passing in the state => state function.

Then we get the dispatch function to useDispatch .

We can use the second argument of the useSelect hook as follows:

import React from "react";
import ReactDOM from "react-dom";
import { Provider, useSelector, useDispatch, shallowEqual } from "react-redux";
import { createStore } from "redux";
function count(state = 0, action) {
  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    case "DECREMENT":
      return state - 1;
    default:
      return state;
  }
}
const store = createStore(count);
function App() {
  const count = useSelector(state => state, shallowEqual);
  const dispatch = useDispatch();
  return (
    <div className="App">
      <button onClick={() => dispatch({ type: "INCREMENT" })}>Increment</button>
      <button onClick={() => dispatch({ type: "DECREMENT" })}>Decrement</button>
      <p>{count}</p>
    </div>
  );
}
const rootElement = document.getElementById("root");
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  rootElement
);

React-Redux has a shallowEqual function to compare data to determine when to update data. We can also define our own function to compare the previous and current state to determine updates.

Conclusion

We can use the useSelector hook to get the data from the Redux store in a React component.

It takes 2 arguments. The first argument is a function that returns the state, and the second argument is a function that checks if the previous and current state are equal to determine when to update.