【问题标题】:React Native: How can I use the DeviceInfo isTablet() method to conditionally apply a style to an element?React Native:如何使用 DeviceInfo isTablet() 方法有条件地将样式应用于元素?
【发布时间】:2019-09-25 16:05:08
【问题描述】:

我正在尝试使我的应用程序的设计适应平板电脑,检测应用程序是否在平板电脑上运行的一种方法是使用 DeviceInfo 模块,尤其是 isTablet() 方法。如何使用此方法有条件地将样式应用于元素?

这是我目前正在尝试做的事情:

import { checkIfDeviceIsTablet } from './helper-functions';

<View style={[styles.wrapper, checkIfDeviceIsTablet() === true ? styles.wrapperTablet : {}]}>
    {contents}
</View>

checkIfDeviceIsTablet()函数如下:

import DeviceInfo from 'react-native-device-info';

function checkIfDeviceIsTablet() {

    DeviceInfo.isTablet().then(isTablet => {
        return isTablet;
    });

}

问题在于,当组件加载时,checkIfDeviceIsTablet() 方法返回一个承诺,而不是预期的真/假值,因此当应用程序在平板电脑上运行时,条件样式不会应用。我尝试使用 try/catch 将函数转换为 async/await 格式,但结果是一样的。

我会使用 React Native 自己的 Platform.isPad 函数,但该应用也必须在 Android 上运行。

感谢任何帮助。

【问题讨论】:

    标签: react-native react-native-device-info


    【解决方案1】:

    我建议您在应用开始时只调用一次DeviceInfo.isTablet()。您可以将结果全局存储,然后您可以稍后检查类型,而无需处理异步承诺。

    要全局存储类型,您的选择是:

    • 一个全局变量
    • React 的上下文 API
    • 类的静态属性(如果使用 ES6+)
    • 某种全局状态管理解决方案,例如 Redux

    您仍然需要处理最初的异步问题,因为第一次调用 DeviceInfo.isTablet() 将返回一个异步承诺。

    我建议查看 React 的 Context API。

    这是一个粗略的例子:

    render() {
       return (
          <DeviceInfoContext.Consumer>
          { ({ isTablet }) => (
             <Text>Is this a tablet? {isTablet}</Text>
          ) }
          </DeviceInfoContext.Consumer>
       )
    }
    

    你的DeviceInfoContext 类看起来像这样:

    class DeviceInfoContext extends React.Component {
       state = {
          isTablet: false
       }
    
       componentDidMount() {
          Device.IsTablet().then(result => this.setState({ isTablet: result }))
       }
    
       render() {
          return (
             this.props.children({ isTablet: this.state.isTablet })
          )
       }
    }
    
    

    这只是一个粗略的例子。您可以了解更多关于 Context API in the docs

    【讨论】:

    • 感谢您的有用回复@barak.m。我的应用程序正在使用 Redux,因此我在一个操作中实现了对 Device.IsTablet() 的调用,然后我在应用程序的第一个屏幕中调用了该操作。即使我确实注意到第一次加载返回一个承诺而不是预期的真/假,它也能正常工作。当我在其他视图或后续重新加载时(我使用 Redux Persist)读取状态时,它确实具有预期值。
    • @Hols 很高兴为您提供帮助!第一次调用 `DeviceInfo.isTablet()` 总是会返回一个 Promise。那部分你无法改变,但你可以解决它。这个想法是在 Promise 返回一个真/假值后重新渲染。所以第一次渲染不会知道 isTablet 的值,但是所有后续的渲染都会知道。这是 React 方法的一个常见挑战,您必须接受事情可以异步发生并确保您的 UI 向用户显示适当的内容(如加载指示器等)
    【解决方案2】:

    React Native 0.5xx 到 0.6xx 的破坏性变化我也遇到了一些麻烦。设备检测库将其结构更改为 Promise。一幅画。

    这个库节省了一天,安装和使用非常容易。 https://github.com/m0ngr31/react-native-device-detection

    import { isTablet } from 'react-native-device-detection;
    
    // isTablet is a boolean. Return false o true immediately
    
    //So ...
    
    import styled from 'styled-components/native';
    import theme from 'styled-theming';  
    import { isTablet } from 'react-native-device-detection';
    
    const CoverPageDateText = styled.Text`
    font-size: ${isTablet ? 23 : 17};
    color: gray; 
    padding-bottom: 9;
    `
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-09
      • 2023-01-19
      • 2017-08-23
      • 1970-01-01
      • 2014-12-08
      • 2019-08-05
      • 1970-01-01
      • 2010-12-22
      相关资源
      最近更新 更多