首页 > 解决方案 > React 样式 - 溢出问题 - Expo & Electron 单一工作流程

问题描述

我在为 react 中的元素设计样式而苦苦挣扎,作为该语言的完整新手,我会喜欢这个很棒的社区的一些帮助。我遇到了动态的可滚动内容区域和溢出问题。在反应版本(见下文)中,容器已展开,导致窗口具有滚动条。在下面的 html 版本中,您可以看到我希望 UI 如何通过左侧的滚动部分来查看。

与其用大量代码(有很多代码)使这篇文章变得混乱,不如在https://gitlab.com/tgtmedialtd/smartcloud/core/tree/master/package/interface找到接口的源文件

原型版本的源文件可以在https://gitlab.com/tgtmedialtd/smartcloud/core/tree/master/package/desktop找到

如果您想运行其中任何一个,只需yarn install && yarn start在克隆文件后执行

HTML + CSS || 原型版本

原型版本

反应原生 || 构建版本

构建版本

标签: reactjsreact-nativeflexboxreact-native-flatlistreact-component

解决方案


TLDR:maxHeight: 50% == 50%screenHeight不像50%windowHeight我所期望的那样。使用react.Dimensions& Listeners 解决远程调整大小

好的,所以即使没有多少人看过这篇文章,也可能永远不会,我发现了我的问题。

我正在使用的工作流程的快速解释:

使用 React-Native 我正在为移动、网站和桌面应用程序动态渲染内容。这是通过使用 Expo 和 Electron 来管理的。更多信息可以在这里找到:https ://docs.expo.io/versions/v36.0.0/guides/using-electron/

研究/发现

所以我花了很长时间研究类、样式和其他渲染方法,直到我最终确定了样式设置maxHeight。将此设置为50%我期望元素占窗口的 50%。然而,事实并非如此。

最大高度:50%

这很快导致意识到反应选择找到屏幕高度而不是窗口高度......

现在到解决方案。

由于我正在使用的工作流程,要解决它并不像我最初想象的那么容易,在使用electron/remote. 幸运的是,这可以通过一个名为*.electron.tsx. 所以这就是我最终这样做的方式。

//global.tsx - Lines commented out are included in global.electron.tsx
import React from 'react';
import { Platform, Text, View, Image, Dimensions } from 'react-native';
import * as styles from '../assets/styles/main'
import { Example } from './chat/example'
import { ChannelSelect } from './channels/select'
import { ChannelOptions } from './channels/options'

// let remote, win
// try { remote = require('electron').remote }catch(_){}
// try { win = remote.getCurrentWindow() }catch(_){}

export class Container extends React.Component {
  state = {
    showMenu: false,
    style: {},
    height: Dimensions.get("window").height,
    width: Dimensions.get("window").width
  }

  handler = (dims:any) => this.setState(dims);
  // logger = () => {
  //   const winHeight = win.getSize()[1];
  //   this.setState({height: winHeight});
  // };


  constructor (props) {
    super(props);
    this.handleToggleClick = this.handleToggleClick.bind(this);
    this.TopBar = this.TopBar.bind(this);
  }

  componentDidMount() {
    Dimensions.addEventListener("change", this.handler);
    // win.on("will-resize", this.logger)
    if (Platform.OS !== 'web') {
      this.setState({
        style: {position: 'absolute', zIndex: 2, left: 0, top: 0, borderRightWidth: 3, borderColor: styles.colours.b5}
      })
    }
  }

  componentWillUnmount() {
    Dimensions.removeEventListener("change", this.handler);
  }

  async handleToggleClick (){
    if (this.state.showMenu) {
      this.setState({showMenu: false})
    } else {
      this.setState({showMenu: true })
    }
  }

  TopBar (props) {
    return (
      <View key="ChannelContentTopBar" style={styles.global.topBar} >
      {
        Platform.OS!=='web' ? ([
          <View onTouchEnd={this.handleToggleClick} style={{flex: 1, marginLeft: 10, alignContent: 'flex-start', justifyContent: 'flex-start'}}>
            <Image source={require('../assets/img/icon.png')} style={{height:50, width:50}}/>
          </View>,
          <View style={{flex: 3, alignContent: 'center', justifyContent: 'center'}}>
            <Image source={require('../assets/img/logo_sub.png')} style={{height:30, width: 150, alignSelf: 'center'}}/>
          </View>,
          <View style={{flex: 1, alignContent: 'flex-end', justifyContent: 'flex-end'}} />
        ]) : null
      }
      </View>
    )
  }

  render() {
    const {height, width} = this.state;
    // const {height, width} = this.state;
    // let containHeight: number
    // if (Platform.OS=='web') {containHeight = height-20}else{containHeight = height}
    return (
      <View key="container" style={[styles.global.container, {maxHeight: height, maxWidth: width}]}>
       { this.state.showMenu || Platform.OS=='web' ?  ( [
         <View key="selectContainer" style={[styles.channels.Container, this.state.style]}>
            <ChannelSelect />
            <ChannelOptions />
        </View>
      ]) : null }
      {
        this.state.showMenu && Platform.OS!=='web' ? (
          <View key="mainContent" style={styles.global.mainContent} onTouchEnd={this.handleToggleClick}>
            <this.TopBar />
            <Example />
          </View>
        ) : (
          <View key="mainContent" style={styles.global.mainContent}>
            <this.TopBar />
            <Example />
          </View>
        )
      }
      </View>
    )
  }
}

工作版本

我确信有一种更好、更简洁的方法可以做到这一点,但就目前而言,它可以工作并且可以满足我的需要。如果我改进此代码,我将更新脚本并留下注释。现在我终于可以开始修复一些样式问题了 xD

编辑一:为了整理我的代码,我将这一切移到我的全局容器中,以定义一次窗口的大小。


推荐阅读