You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native 屏幕旋转时如何更新尺寸实现组件自适应调整

报错原因

你触发Invalid hook call错误的核心原因是:useState、useEffect属于React Hooks,只能在React函数组件、自定义Hook的顶层作用域调用,你在普通JS文件的普通函数里调用Hooks,不符合Hooks的使用规则。
另外你当前的样式是初始化时静态生成的,直接写死了初始的屏幕宽高,就算监听生效,静态样式也不会自动更新,自然无法适配旋转后的尺寸。

可行实现方案

推荐使用React Native官方自带的useWindowDimensions Hook,它会自动监听屏幕尺寸变化,无需手动维护Dimensions监听器,实现步骤如下:

1. 修改Styles.js,改为动态生成样式

不要导出静态的样式对象,改为导出一个接收当前屏幕宽高为参数的函数,动态生成对应尺寸的样式:

import { StyleSheet, Dimensions } from "react-native";
import { scale, ScaledSheet } from "react-native-size-matters";

// 改为接收宽高参数的函数,动态生成样式
export const getStyles = (windowWidth, windowHeight) => ScaledSheet.create({
  scrollViewContainer: {
    backgroundColor: '#E20030',
    alignItems: 'center',
    height: windowHeight,
    padding: '50@s'
  },
  container2: {
    alignItems: 'center',
    justifyContent: 'center',
    width: windowWidth,
    flex: 1,
  },
  loginRect: {
    borderRadius: '30@s',
    marginTop: '20@s',
    width: windowWidth * 0.8,
    backgroundColor: 'white',
    alignItems: 'center'
  },
  SectionStyle: {
    flexDirection: 'row',
    marginTop: 0,
    marginLeft: '35@s',
    marginRight: '35@s',
    borderWidth: '1@s',
    borderRadius: '5@s',
    borderColor: '#dadae8',
  },
  // 你之前缺失的input、buttonTextStyle样式也可以在这里补充
});

2. 修改Login.js,使用useWindowDimensions获取实时尺寸

在登录组件内调用useWindowDimensions获取实时的宽高,再传入样式生成函数得到当前适配的样式:

import React from 'react';
import {
    Text, View, TextInput, TouchableOpacity,
    KeyboardAvoidingView,
    useWindowDimensions // 导入官方Hook
} from 'react-native';
import { getStyles } from './Components/styles'; // 导入样式生成函数

const LoginScreen = () => {
    // 获取实时屏幕宽高,旋转时会自动更新
    const { width: windowWidth, height: windowHeight } = useWindowDimensions();
    // 生成当前尺寸对应的样式
    const { mystyles, styles } = getStyles(windowWidth, windowHeight);

    return (
        <View style={mystyles.scrollViewContainer}>
            <KeyboardAvoidingView behavior="padding" style={{ flex: 100 }}>
                <View style={mystyles.scrollViewContainer}>
                    <View style={mystyles.loginRect}>
                        <View style={{ flexDirection: 'row' }}>
                            <View style={{ flex: 1, marginLeft: 45, marginTop: 20 }}>
                                <Text style={{ color: 'black' }}>Username</Text>
                            </View>
                        </View>
                        <View style={styles.SectionStyle}>
                            <TextInput style={styles.input} />
                        </View>
                        <View style={{ flexDirection: 'row' }}>
                            <View style={{ flex: 1, marginLeft: 45, marginTop: 20 }}>
                                <Text style={{ color: 'black' }}>Password</Text>
                            </View>
                        </View>
                        <View style={styles.SectionStyle}>
                            <TextInput style={styles.input} />
                        </View>
                        <TouchableOpacity>
                            <Text style={styles.buttonTextStyle}>LOGIN</Text>
                        </TouchableOpacity>
                    </View>
                </View>
            </KeyboardAvoidingView>
        </View>
    )
}

export default LoginScreen;

方案说明

  • 屏幕旋转时useWindowDimensions会自动返回最新的宽高数值,触发组件重渲染,样式会根据新的尺寸重新生成,自动适配布局
  • 不需要手动维护Dimensions监听器,也避免了Hooks使用错误的问题

内容的提问来源于stack exchange,提问作者Benson Kiprono

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 01:06:07