反应本机视图上的选择器放置错误

Picker placement is wrong on react-native view

我正在关注此 Udemy react-native course,在其中一个示例中,他使用选择器 select 屏幕中的数据。当他尝试它时,它似乎可以正常工作,但现在当我尝试渲染它时,我得到了一个奇怪的结果。

如果我完全按照他的代码,选择器会在所有其他项目之后显示,在进行一些更改后,我会在正确的位置显示它,但它现在被压扁了,这仍然不正确:

我肯定在渲染方面做错了,这里是代码 (full example on github):

import React from 'react';
import {Picker, Text, StyleSheet, View} from 'react-native';
import {connect} from 'react-redux';
import {Card, CardSection, Input, Button} from "./common";
import {employeeUpdate} from "../actions";

class EmployeeCreate extends React.Component {

  updateEmployee(name, value) {
    this.props.employeeUpdate({prop: name, value: value})
  }

  renderPickerItems() {
    return ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
      .map((item) => <Picker.Item key={item} label={item} value={item}/>);
  }

  render() {
    return (
      <Card>

        <CardSection>
          <Input
            label="Name"
            placeholder="Your Name"
            value={this.props.name}
            onChangeText={this.updateEmployee.bind(this, 'name')}
          />
        </CardSection>

        <CardSection>
          <Input
            label="Phone"
            placeholder="555-555-5555"
            keyboardType="phone-pad"
            value={this.props.phone}
            onChangeText={this.updateEmployee.bind(this, 'phone')}
          />
        </CardSection>

        <CardSection style={{flex: 1}}>
          <View style={styles.shiftContainerStyle}>
            <Text style={styles.pickerTextStyle}>Shift</Text>
            <Picker
              style={styles.pickerStyle}
              selectedValue={this.props.shift}
              onValueChange={this.updateEmployee.bind(this, 'shift')}
            >
              {this.renderPickerItems()}
            </Picker>
          </View>
        </CardSection>

        <CardSection>
          <Button>
            Create
          </Button>
        </CardSection>

      </Card>
    );
  }

}

const styles = StyleSheet.create({
  pickerTextStyle: {
    fontSize: 18,
    lineHeight: 23,
    flex: 1,
  },
  pickerStyle: {
    flex: 2,
  },
  shiftContainerStyle: {
    flex: 1,
    flexDirection: 'row',
    alignItems: 'center',
  }
});

const mapStateToProps = state => {
  const {name, phone, shift} = state.employeeForm;

  return {
    name,
    phone,
    shift,
  };
};

export default connect(mapStateToProps, {employeeUpdate})(EmployeeCreate);

知道我可以做些什么来正确渲染它吗?

您需要从代码中的这一行删除 style={{flex: 1}}

<CardSection style={{flex: 1}}>

原因是您的父容器 Card 没有定义任何 flexwidth/height 值。如果 flex 未定义,. If you look at the docs for flex,您将看到:

When flex is 0, the component is sized according to width and height and it is inflexible.

将其与未定义 width/height 相结合,您会在呈现 CardSections 时获得此行为:

  • 这三个 CardSection(输入、输入、按钮)将根据其子项占用默认的 widthheight。这是 InputButton.
  • 的默认样式
  • 带有style={{flex: 1}}CardSection会根据每个父容器占用的剩余space来计算其widthheight flex: 1的定义:

When flex is a positive number, it makes the component flexible and it will be sized proportional to its flex value. So a component with flex set to 2 will take twice the space as a component with flex set to 1.

  • 父容器 Card,在本例中没有多余的 space。所以发生的是这个 CardSection 以 0 height 结束。因此,您会看到奇怪的溢出渲染。

删除 style={{flex: 1}} 后,CardSectionwidthheight 将由其子组件定义,例如 InputButton,确实有样式和默认样式。

根据我链接到的Yoga spec (Yoga is what React Native uses for layout) is up for debate and has tripped up others before. Definitely look over that ,这是否是正确的行为,因为它比 React Native wrt flex.[=51 上的任何文档都有更多关于陷阱的详细信息和解释=]