1

我在这个错误上花了几个小时,我希望另一双眼睛可以帮助我!感谢您的帮助!

我有一个 React Native 应用程序,在 Modal 中,我有一个带有单选按钮的选项列表。

我想要什么:当您单击模型列表中的 TouchableHighlight 项目时,我希望单选按钮移动到用户按下的项目。换句话说,我想设置单选按钮,就selected好像我按下了我点击的项目的rowId一样。

发生了什么:当我关闭 Modal 并重新打开时,我看到单选按钮已移动到正确的选项,但问题是我需要单选按钮在单击时立即移动!因此,我设置了正确的状态,但在我重新打开 Modal 之前,组件不会重新渲染。

这是我的自定义单选按钮组件:

    export default RadioButton = ({style, selected}) => {
  return (
      <View style={[{
        height: 24,
        width: 24,
        borderRadius: 12,
        borderWidth: 2,
        borderColor: colors.primaryText,
        alignItems: 'center',
        justifyContent: 'center',
      }, style]}>
        {
          selected ?
            <View style={{
              height: 16,
              width: 16,
              borderRadius: 8,
              backgroundColor: colors.primaryText,
            }}/>
            : null
        }
      </View>
  );
}

我有一个处理状态的容器组件:

    class ShippingDetails extends Component {
      constructor(props){
        super(props)
        const ds = new ListView.DataSource({rowHasChanged: (r1, r2, ) => r1 !== r2 });
        const deliveryOptions = ['USPS Mail', 'USPS Next Day'] //will be replaces with redux
        this.state = {
          dataSource: ds.cloneWithRows(deliveryOptions),
          shippingMethod: null,
          modalVisible: false,
          selectedOption: 0
        };
      }

      _handleShippingMethodPress = (selected, id) => {
        this.setState({shippingMethod: selected})
        this.setState({selectedOption: id})
      }

      renderShippingMethods = (shippingMethod, sectionID, rowID, highlightRow) => {
        return (
          <SelectShippingMethod 
            onPress={() => this._handleShippingMethodPress(shippingMethod, rowID)}
            shippingMethod={shippingMethod}
            price={'Free Shipping'}
            date={'Expected delivery March 12'}
            selected={this.state.selectedOption == rowID}
          />
        )
      }
  render () {
    return (
      <View style={backgroundApp}>

            <View>
              <SelectShippingMethod 
                shippingMethod={shippingMethod}
                onPress={() => this.setModalVisible(true)}
                price={'Free Shipping'} //replace with redux price
                date={'Expected delivery March 12'}
                singleRow={true}
              />
                <Modal
                  animationType={"slide"} //slide and fade
                  transparent={false}
                  visible={this.state.modalVisible}
                  onRequestClose={()=>{console.warn('callback for onRequestClose Modal in ShippingDetails')}} //
                  >
                  <ShippingMethodOptions 
                    dataSource={this.state.dataSource}
                    renderRow={this.renderShippingMethods}
                    renderSeparator={Separator}
                    closeModal={() => this.setModalVisible(false)} 
                  /> 
                </Modal>
         </View>
      </View>
    )
  }
}

SelectShippingMethod 是一个组件,它返回各个 TouchableHighlight 项,并selected作为来自容器组件的 prop 传递。

return(
        <TouchableHighlight 
            onPress={onPress}>
            <View style={[rowWrapper, {alignItems: 'center', paddingLeft: 5}]}>
                { !singleRow && <RadioButton selected={selected}/>}
                <View style={styles.methods}>
                    <Text style={descriptionColor}>{description}</Text> 
                    <Text style={subHeader}>{shipDate}</Text>
                </View>
                <Text style={styles.price}>{shipPrice}</Text>
                {/*<Icon name="ios-arrow-forward" size={17} color={colors.iconGrey} style={arrows}/>*/}
            </View>
        </TouchableHighlight>
    )

ShippingMethodOptions 是一个包裹 ListView 并向下传递适当道具的组件。

const ShippingMethodOptions = ({dataSource, renderRow, renderSeparator, closeModal}) => {
  return(
        <View style={backgroundApp}>
      <NavHeader closeModal={closeModal}/>
      <Text style={[subHeader, textSection]}></Text>
      <View style={hr}></View>

      <ListView 
        dataSource={dataSource}
        renderRow={renderRow}
        renderSeparator={renderSeparator} 
      />
    </View>
    )
}

当我使用 Fiber 升级到 React 16 时,我注意到单选按钮按预期工作,所以这让我想知道一些事情。

  1. 光纤的速度快到我可以编写更错误的代码了吗?

  2. 使用更新的 React 版本时,Modal 组件中的生命周期方法有什么不同吗?

  3. setState 有什么不同导致更多的东西用纤维重新渲染吗?

更新 我已经在控制台记录了这个过程,我看到在按下一个项目后,ListView 上的 renderRow 不会再次被调用,而是 SelectedShippingMethod 被选中并被调用undefined。为什么会发生这种情况,我怎样才能让它工作?

4

0 回答 0