开发者问题收集

在组件子项的第一个位置添加一个子项

2019-06-04
429

我为 Picker 组件创建了一个包装器,并且我想在条件中添加一个子项

我尝试此代码

render() {
    const { children, ...rest } = this.props;

    return (
      <Picker {...rest}>
        {rest.selectedValue === undefined ? (
          <Picker.Item value="1" label="1" />
        ) : null}
        {children}
      </Picker>
    );
  }

然后我收到此错误

TypeError: null is not an object(evaluating 'o.props')

我也尝试使用 undefineed 而不是 nullshort circuit 条件,但是在这种情况下我也收到错误。

请注意,如果我删除条件并在子项之前添加一个元素,它就可以工作。类似这样的事情

<Picker.Item value="1" label="1" />
{children}

已更新

我发现问题是当条件为假时,例如这会产生错误

{false && (<Picker.Item value="1" label="1" />)}

expo 项目 https://snack.expo.io/@cooper47/mad-waffle ( 更改选择器并查看错误 )

我认为问题是当我将 childrenundefined (条件的结果)连接起来时,因为当我尝试这样做时会得到相同的错误

<Picker {...rest}>
   {undefined} // result of short circuit 
   {children} 
</Picker>
  • 为什么我在有条件的情况下会得到这个错误,而在没有条件的情况下不会得到错误条件?

  • 如何在 this.props.children 之前添加元素?

  • 有没有办法在 children 的开头添加元素?例如 children.add(<Picker.Item...>)

我发现它实际上是 react-native 中的一个错误

这是相关问题 https://github.com/facebook/react-native/issues/25141#issuecomment-498651856

2个回答

Note: There is no problem with the condition, the error depends on the wrapper (Picker) internal calls.

我的猜测是 Picker 内部调用其子 props(期望 Picker.Item ),当它为假时它可能会检查你的条件 props ,因此抛出 undefined props 的错误。

<Picker>
  {condition && <Picker.Item value="1" label="1" />}   
  // ^ Picker wrapper may check null.props, undefined.props, false.props etc

  {children}
</Picker>

在这种情况下,请在渲染之外制定条件:

const conditionChildren = condition ? (
    <> <Picker /> {children} </> ) : (children);
  return {conditionChildren}

How I can add an element before this.props.children?

使用 React.createElement 或调用组件内联:

function ConditionChildren({ children, condition }) {
  return (
    <>
      {condition && <Picker />}
      // or {condition && React.createElement(Picker)}
      {children}
    </>
  );
}

Is there anyway add an element at first of children? for example children.add()

const addFirstToChildren = [
    React.createElement(Picker),
    ...React.Children.toArray(children)
  ];
return {addFirstToChildren}

使用通用解决方案检查演示:

Edit zealous-heyrovsky-exec8

Dennis Vash
2019-06-04

尝试使用下面的代码来实现 PureComponent

import React, { PureComponent } from 'react'
import { View, Text, TouchableOpacity, Picker } from 'react-native'

export default class SelectBox extends React.PureComponent {
    constructor(props) {
    super(props)
    }
    render() {
     const { options, value, onChageText } = this.props
      let Alloptions = options.map((item, key) => {
         return (<Picker.Item label={item.name} value={item.value} key={key} />)
      })
      return (
        <Picker selectedValue={value} onValueChange={onChageText}>
       {/* If you want to add default option here  */}
         {/* <Picker.Item label="Select Location..." value="" /> */}
              {Alloptions}
        </Picker>
     )
    }
}

以及你的组件

<SelectBox
options={[{name:'aaa',value:'11'},{name:'bbbb',value:'22'}]}
value={''}
onChageText={this.selectLocation}
/>
 selectLocation(itemValue, itemIndex) {
...your code
}

谢谢

vd_virani
2019-06-04