React Native

    Flexbox for React-native

    Published
    April 21, 2023
    Reading Time
    4 min read
    Author
    Felix
    Access
    Public

    1. About Flexbox

    Before flexbox was introduced into css, the various css properties for building layouts were rough and error-prone. And flexbox solves the problem by abstracting many properties. As the name suggests, flexbox means a flexible box model. Let's draw a picture: assuming you have a container and its child elements, it could look like this.

    image.png

    Flexbox containers have two axes, namely column (up/down) or row (left/right).

    2. Practical operation

    Let’s go straight to the code. This is a js module, not a css module. If we want to declare a style for rn, we need to define an object and then call StyleSheet.create() and finally throw it out of your module. But we need to note that rn only supports camel case naming.

    import { Platform, StyleSheet, StatusBar } from 'react-native'
    export default StyleSheet.create({
      container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: 'ghostwhite',
        ...Platform.select({
          ios: { paddingTop: 20 },
          android: { paddingTop: StatusBar.currentHeight },
        }),
      },
      box: {
        width: 100,
        height: 100,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: 'lightgray',
      },
      boxText: {
        color: 'darkslategray',
        fontWeight: 'bold',
      },
    })
    
    
    

    Then we saw that I just wrote this piece of code, which actually selects the style according to your mobile terminal.

    ...Platform.select({
      ios: { paddingTop: 20 },
      android: { paddingTop: StatusBar.currentHeight },
    }),
    
    

    ok, let’s take a look at how to use it in the rn component

    import { Text, View } from 'react-native'
    import styles from './styles'
    export default function App() {
      return (
        <View style={styles.container}>
          <View style={styles.box}>
            <Text style={styles.boxText}>I'm in a box</Text>
          </View>
        </View>
      )
    }
    
    
    

    These styles will be assigned to each component via style properties. Let's see how it performs.

    image.png

    3. Use of Styled-components style component library

    Styled-components is a css-in-js library that provides styles for our components. Let’s see how to use it directly. Of course, it’s just an introduction, we still use styleSheet.

    First download the dependencies

    yarn add styled-components
    
    

    Then we write some code

    import styled from "styled-components/native";
    const Box = styled.View'
        width: 100px;
        height: 100px;
        justify-content: center;
        align-items: center;
        background-color: lightgray;
    ';
    const BoxText = styled.Text'
        color: darkslategray;
        font-weight: bold;
    ';
    
    

    Use

    const App = () => {
    return (
        <Box>
            <BoxText>I'm in a box</BoxText>
        </Box>
    );
    
    };
    
    

    4. Basic Flexbox

    Next, we will mainly talk about several common layouts in rn and the actual combat of flexbox

    4.1. Three-column layout

    A common three-column layout from top to bottom.

    image.png

    You can understand view as div and text as p.

    import { Text, View } from 'react-native'
    import styles from './styles'
    export default function App() {
      return (
        <View style={styles.container}>
          <View style={styles.box}>
            <Text style={styles.boxText}>#1</Text>
          </View>
          <View style={styles.box}>
            <Text style={styles.boxText}>#2</Text>
          </View>
          <View style={styles.box}>
            <Text style={styles.boxText}>#3</Text>
          </View>
        </View>
      )
    }
    
    

    The flexDirection property determines the direction of the main axis, top to bottom or left to right, while the alignItem and justifyContent properties determine the arrangement and spacing of elements.

    import { Platform, StyleSheet, StatusBar } from 'react-native'
    export default StyleSheet.create({
      container: {
        flex: 1,
        flexDirection: 'column',
        alignItems: 'center',
        justifyContent: 'space-around',
        backgroundColor: 'ghostwhite',
        ...Platform.select({
          ios: { paddingTop: 20 },
          android: { paddingTop: StatusBar.currentHeight },
        }),
      },
      box: {
        width: 300,
        height: 100,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: 'lightgray',
        borderWidth: 1,
        borderStyle: 'dashed',
        borderColor: 'darkslategray',
      },
      boxText: {
        color: 'darkslategray',
        fontWeight: 'bold',
      },
    })
    
    
    

    And what if we want it to fill up the left and right sides? like this

    image.png

    We can add the attribute alignSelf, which means to change the width or height according to the direction of the main axis flexDirection (column changes the width, row changes the height) to fill the blanks and dynamically calculate the height or width. Like this it will fill the width of your screen.

      box: {
        height: 100,
        justifyContent: 'center',
        //
        alignSelf: 'stretch',
        alignItems: 'center',
        backgroundColor: 'lightgray',
        borderWidth: 1,
        borderStyle: 'dashed',
        borderColor: 'darkslategray',
      },
    
    

    When we turn our cell phones sideways

    image.png

    Let's optimize it a little and just write the horizontal layout. The above style is too "abstract" to write.

    import { Text, View, StatusBar } from 'react-native'
    import styles from './styles'
    import Box from './Box'
    export default function App() {
     return (
       <View style={styles.container}>
         <Box>#1</Box>
         <Box>#2</Box>
       </View>
     )
    }
    
    
    
    import { PropTypes } from 'prop-types'
    import { View, Text } from 'react-native'
    import styles from './styles'
    export default function Box({ children }) {
     return (
       <View style={styles.box}>
         <Text style={styles.boxText}>{children}</Text>
       </View>
     )
    }
    Box.propTypes = {
     children: PropTypes.node.isRequired,
    }
    
    

    This is a horizontal layout that stretches to the entire height of the screen.

    import { Platform, StyleSheet, StatusBar } from 'react-native'
    export default StyleSheet.create({
      container: {
        flex: 1,
        flexDirection: 'row',
        backgroundColor: 'ghostwhite',
        alignItems: 'center',
        justifyContent: 'space-around',
        ...Platform.select({
          ios: { paddingTop: 20 },
          android: { paddingTop: StatusBar.currentHeight },
        }),
      },
      box: {
        width: 100,
        justifyContent: 'center',
        alignSelf: 'stretch',
        alignItems: 'center',
        backgroundColor: 'lightgray',
        borderWidth: 1,
        borderStyle: 'dashed',
        borderColor: 'darkslategray',
      },
      boxText: {
        color: 'darkslategray',
        fontWeight: 'bold',
      },
    })
    
    
    

    Let's see how it performs

    ![image.png](https://ik.imagekit.io/leiakito/react%20Core%20scheduling%20principles/react-native-flexbox/1 b7f4a002d1045a882faf4b2a2ea521a~tplv-k3u1fbpfcp-zoom-in-crop-mark_1512_0_0_0.webp?updatedAt=1739875782894)

    When we turn our cell phones sideways

    ![image.png](https://ik.imagekit.io/leiakito/react%20Core%20scheduling%20principles/react-native-flexbox/4 bf95f1a6db64d708edd014bbab07159~tplv-k3u1fbpfcp-zoom-in-crop-mark_1512_0_0_0.webp?updatedAt=1739875782855)

    5. A slightly more complicated flexBox

    Suppose we want to achieve such an effect, how should we achieve it?

    ![image.png](https://ik.imagekit.io/leiakito/react%20Core%20scheduling%20principles/react-native-flexbox/4 da8595a2c834d6ba5bdabc8e1dd8882~tplv-k3u1fbpfcp-zoom-in-crop-mark_1512_0_0_0.webp?updatedAt=1739875781677)

    In our consciousness, the entire layout has rows and columns. Then we can also abstract the col and row components to represent the rows and columns respectively. Let’s jump right into the code.

    You can see that we have determined the direction and arrangement of col and row respectively.

    import { Platform, StyleSheet, StatusBar } from 'react-native'
    
    export default StyleSheet.create({
      container: {
        flex: 1,
        flexDirection: 'column',
        backgroundColor: 'ghostwhite',
        alignItems: 'center',
        justifyContent: 'space-around',
        ...Platform.select({
          ios: { paddingTop: 40 },
          android: { paddingTop: StatusBar.currentHeight },
        }),
      },
    
      box: {
        height: 100,
        width: 100,
        justifyContent: 'center',
        alignItems: 'center',
        borderWidth: 1,
        borderStyle: 'dashed',
        borderColor: 'darkslategray',
        backgroundColor: 'lightgray',
      },
    
      boxText: {
        color: 'darkslategray',
        fontWeight: 'bold',
      },
    
      row: {
        flex: 1,
        flexDirection: 'row',
        justifyContent: 'space-around',
        alignSelf: 'stretch',
      },
    
      column: {
        flex: 1,
        flexDirection: 'column',
        alignItems: 'center',
        justifyContent: 'space-around',
        alignSelf: 'stretch',
      },
    })
    
    

    Components Section

    app

    import { View, StatusBar } from 'react-native'
    import styles from './styles'
    import Row from './Row'
    import Col from './Col'
    import Box from './Box'
    
    export default function App() {
      return (
        <View style={styles.container}>
          <StatusBar hidden={false} />
          <Row>
            <Col>
              <Box>#1</Box>
              <Box>#2</Box>
            </Col>
            <Col>
              <Box>#3</Box>
              <Box>#4</Box>
            </Col>
          </Row>
          <Row>
            <Col>
              <Box>#5</Box>
              <Box>#6</Box>
            </Col>
            <Col>
              <Box>#7</Box>
              <Box>#8</Box>
            </Col>
          </Row>
          <Row>
            <Col>
              <Box>#9</Box>
              <Box>#10</Box>
            </Col>
            <Col>
              <Box>#11</Box>
              <Box>#12</Box>
            </Col>
          </Row>
        </View>
      )
    }
    
    
    

    col

    import PropTypes from 'prop-types'
    import { View } from 'react-native'
    import styles from './styles'
    
    export default function Column({ children }) {
      return <View style={styles.column}>{children}</View>
    }
    
    Column.propTypes = {
      children: PropTypes.node.isRequired,
    }
    
    
    

    row

    import PropTypes from 'prop-types'
    import { View } from 'react-native'
    import styles from './styles'
    
    export default function Row({ children }) {
      return <View style={styles.row}>{children}</View>
    }
    
    Row.propTypes = {
      children: PropTypes.node.isRequired,
    }
    
    
    

    box

    import React from 'react'
    import PropTypes from 'prop-types'
    import { View, Text } from 'react-native'
    import styles from './styles'
    
    export default function Box({ children }) {
      return (
        <View style={styles.box}>
          <Text style={styles.boxText}>{children}</Text>
        </View>
      )
    }
    
    Box.propTypes = {
      children: PropTypes.node.isRequired,
    }
    
    

    6. Summary

    In this section, we know the most common layout method in rn. Students need to practice more by themselves. It is relatively simple. If you have any questions, you can ask me. Join the study group to watch Boiling Point.

    Comments

    Join the conversation

    0 comments
    Sign in to comment

    No comments yet. Be the first to add one.