22

I'm creating a basic login using React Native with a logo and 2 inputs:

//import liraries
import React, { Component } from 'react';
import { View, Text, StyleSheet, Image } from 'react-native';

// create a component
class Login extends Component {
    render() {
        const imageURL = require('./images/CircleLogo.png');
        return (
            <View style={styles.container}>
                <View style={styles.loginContainer}>
                    <Image resizeMode="contain" style={styles.logo} source={imageURL} />
                </View>
                <View style={styles.formContainer}>
                    <LoginForm /> 
                </View>
            </View>
        );
    }
}

// define your styles
const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: 'aliceblue',
    },
    loginContainer:{
        alignItems: 'center',
        flexGrow: 1,
        justifyContent: 'center'
    },
    logo: {
        position: 'absolute',
        width: '70vw',
        height: '70vw',
        maxWidth: 300
    }
});

//make this component available to the app
export default Login;

As you can see i am using vw and vh css measurements.

This works on the web, but not on iOS or Android.

Does anyone have a good suggestion for handling vw and vh measurements?

Side Note: It appears react accepts percentages as seen here, which I may revert to. But my question pertains to specifically the vw and vh measurements.

Dustin Spengler
  • 5,478
  • 4
  • 28
  • 36

4 Answers4

26

Instead of veiwport you can use Dimensions in react-native. PFB the link of react-native Dimensions.

https://reactnative.dev/docs/dimensions

Here is an example:

import { Dimensions } from 'react-native'

const halfWindowsWidth = Dimensions.get('window').width / 2
TOPKAT
  • 6,667
  • 2
  • 44
  • 72
Anupam Chaplot
  • 1,134
  • 1
  • 9
  • 22
  • 6
    This should be the accepted answer! Instead of adding an extra dependency it is save and easy to rely on react-natives preferred `useWindowDimensions` API. It will propagate updates and works seamlessly with react-native-web since v0.12.0. – tjeisenschenk Nov 16 '20 at 13:52
  • Super legit! This is a great way to go about it. – Starfs Oct 12 '21 at 19:38
  • Also package `react-native-viewport-units` breaks on Next JS (Server Side Rendering) at import level, leading to lazy load complication for nothing. – KeitelDOG Feb 22 '22 at 20:55
  • Could you precise exactly what happens if the users changes window size or device orientation ? – TOPKAT Dec 20 '22 at 14:06
11

I don't know if react-native supports viewport units. But, there's a module:

https://www.npmjs.com/package/react-native-viewport-units

Install

npm install react-native-viewport-units --save

Usage

var {vw, vh, vmin, vmax} = require('react-native-viewport-units');

Notice the required operator/syntax: x * vw

<View style={{height:50*vh, width:50*vw}}/>
var styles = StyleSheet.create({
  lookingGood: {
    width: 15*vmin,
    height: 10*vmax,
    padding: 2*vw,
    margin: 4*vh,
  }
});
Bhojendra Rauniyar
  • 83,432
  • 35
  • 168
  • 231
8

Viewport units: vw, vh, vmin, vmax - React Native.

https://github.com/joetakara/react-native-expo-viewport-units

Install

npm install react-native-expo-viewport-units

or

yarn add react-native-expo-viewport-units

Usage

import { vw, vh, vmin, vmax } from 'react-native-expo-viewport-units';

<View style={{ width: vw(100), height: vh(100) }}>
  ...
<View>
2

I've browsed through other answers, all that works and simple for new projects. If you desire to make an existing project responsive, I'd recommend using the below package.

https://www.npmjs.com/package/react-native-responsive-view-port

Assume you've already built an app for 1280 x 800 and you wish to make it responsive for all resolutions, then you can achieve it as shown below.

Before

    <View style={{ width:500 }} ></View>

After

const { vw, vh } = createViewPortConfig({ width : 1280, height : 800 });

<View style={{ width: 500*vw }} ></View>

I find this method easier than recalculating all sizes.

vijay krishna
  • 514
  • 4
  • 14