Besides React style programming, is another cool feature of React Native. It is a cross-platform layout engine which implements Flexbox so we use the same layout code for both platforms. Yoga As someone who uses Auto Layout in iOS and Constraint Layout in Android, I find Flexbox bit hard to use at first, but there are many tasks that Flexbox does very well, they are distribute elements in space and flow layout. In this post we will use Flexbox to build a tag selection view using just Javascript code. This is very easy to do so we don’t need to install extra dependencies. Our tag view will support both multiple selection and exclusive selection. First, we need a custom . Button Button with Background is of the basic elements in React Native, but it is somewhat limited if we want to have custom content inside the button, for example texts, images and background Button import { Button } from 'react-native'... <ButtononPress={onPressLearnMore}title="Learn More"color="#841584"accessibilityLabel="Learn more about this purple button"/> TouchableOpacity Luckily we have , which is a wrapper for making views respond properly to touches. On press down, the opacity of the wrapped view is decreased, dimming it. TouchableOpacity To implement button in our tag view, we need to a button with background a check image. Create a file called BackgroundButton.js import React from 'react'import { TouchableOpacity, View, Text, StyleSheet, Image } from 'react-native'import R from 'res/R' export default class BackgroundButton extends React.Component {render() {const styles = this.makeStyles()return (<TouchableOpacity style={styles.touchable} onPress={this.props.onPress}><View style={styles.view}>{this.makeImageIfAny(styles)}<Text style={styles.text}>{this.props.title}</Text></View></TouchableOpacity>)} makeImageIfAny(styles) {if (this.props.showImage) {return <Image style={styles.image} source={R.images.check} />}} makeStyles() {return StyleSheet.create({view: {flexDirection: 'row',borderRadius: 23,borderColor: this.props.borderColor,borderWidth: 2,backgroundColor: this.props.backgroundColor,height: 46,alignItems: 'center',justifyContent: 'center',paddingLeft: 16,paddingRight: 16},touchable: {marginLeft: 4,marginRight: 4,marginBottom: 8},image: {marginRight: 8},text: {fontSize: 18,textAlign: 'center',color: this.props.textColor,fontSize: 16}})}} Dynamic styles Normally we use but since we want our button to be configurable, we make into a function, so on every we get a new with proper configurations. The properties we support are , , and const styles = StyleSheet.create({}) styles render styles borderColor textColor backgroundColor showImage In the we only need to return if the view is selected. We don’t have the case, so in if is false, this returns and React won’t render any element makeImageIfAny Image else showImage undefined makeImageIfAny(styles) {if (this.props.showImage) {return <Image style={styles.image} source={R.images.check} />}} padding and margin To understand padding and margin, visit . Basically padding means clearing an area around the content and padding is transparent, while margin means clearing an area outside the border and the margin also is transparent. CSS Box Model Pay attention to . We have margin for so that each tag button have a little margin outside each other. styles touchable touchable: {marginLeft: 4,marginRight: 4,marginBottom: 8} In the view we need as because React Native has as by default. And a row means we have and side by side horizontally inside the button. We also use and to align elements centeredly on both main and cross axises. The padding is used to have some spaces between the inner text and the view. flexDirection row flexDirection column Image Text alignItems justifyContent view: {flexDirection: 'row',height: 46,alignItems: 'center',justifyContent: 'center',paddingLeft: 16,paddingRight: 16} Tag View Create a file called This is where we parse tags and show a bunch of TagsView.js BackgroundButton import React from 'react'import { View, StyleSheet, Button } from 'react-native'import R from 'res/R'import BackgroundButton from 'library/components/BackgroundButton'import addOrRemove from 'library/utils/addOrRemove' export default class TagsView extends React.Component {constructor(props) {super(props)this.state = {selected: props.selected}} render() {return (<View style={styles.container}>{this.makeButtons()}</View>)} onPress = (tag) => {let selectedif (this.props.isExclusive) {selected = [tag]} else {selected = addOrRemove(this.state.selected, tag)} this.setState({selected})} makeButtons() {return this.props.all.map((tag, i) => {const on = this.state.selected.includes(tag)const backgroundColor = on ? R.colors.on.backgroundColor : R.colors.off.backgroundColorconst textColor = on ? R.colors.on.text : R.colors.off.textconst borderColor = on ? R.colors.on.border : R.colors.off.border return (<BackgroundButtonbackgroundColor={backgroundColor}textColor={textColor}borderColor={borderColor}onPress={() => {this.onPress(tag)}}key={i}showImage={on}title={tag} />)})}} const styles = StyleSheet.create({container: {flex: 1,flexDirection: 'row',flexWrap: 'wrap',padding: 20}}) We parse an array of tags to build . We keep the array in because this is mutated inside the component. If it is then the new contains just the new selected tag. If it is multiple selection, then we add the new selected tag into the array. BackgroundButton selected state TagsView isExclusive selected selected The addOrRemove is a our homegrown utility function to add an item into an array if it does not exists, or remove if it exists, using the high order function. filter const addOrRemove = (array, item) => {const exists = array.includes(item) if (exists) {return array.filter((c) => { return c !== item })} else {const result = arrayresult.push(item)return result}} Flex wrap Pay attention to styles const styles = StyleSheet.create({container: {flex: 1,flexDirection: 'row',flexWrap: 'wrap',padding: 20}}) The hero here is which specifies whether the flexible items should wrap or not. Take a look at property for other options. Since we have main axis as , element will be wrapped to the next row if there are not enough space. That’s how we can achieve a beautiful tag view. flexWrap CSS flex-wrap row Using TagsView Then consuming TagsView is as easy as declare it inside render const selected = ['Swift', Kotlin]const tags = ['Swift', 'Kotlin', 'C#', 'Haskell', 'Java'] return (<TagsViewall={tags}selected={selected}isExclusive={false}/>) Learning Flexbox Learning Flebox is crucial in using React and React Native effectively. The best places to learn it are and by Mozzila. w3school CSS Flexbox Basic concepts of flexbox _The Flexible Box Module, usually referred to as flexbox, was designed as a one-dimensional layout model, and as a…_developer.mozilla.org Basic concepts of flexbox There is a showcase of all possible Flexbox properties _A simple visual guide with live examples for all major React Native layout properties_medium.com The Full React Native Layout Cheat Sheet Yoga has its own YogaKit published on CocoaPods, you can learn it with native code in iOS _Learn about Yoga, Facebook's cross-platform layout engine that helps developers write more layout code in style akin to…_www.raywenderlich.com Yoga Tutorial: Using a Cross-Platform Layout Engine And when we use flexbox, we should compose element instead of hardcoding values, for example we can use another View with to move a button down the screen. This follows flexbox style and prevent rigid code. justifyContent: flex-end _React Native uses Yoga to achieve Flexbox style layout, which helps us set up layout in a declarative and easy way._medium.com Position element at the bottom of the screen using Flexbox in React Native Where to go from here I hope you learn something useful in this post. For more information please consult the official guide and for all the possible Flexbox properties. Layout with Flexbox layout-props While you are here, you may like my other posts Next to first, next to nothing 20 recommended utility apps for macOS in 2018 Getting to know some pragmatic programming language features 8 ways to communicate between Fragment and Activity in Android apps