我在这个错误上花了几个小时,我希望另一双眼睛可以帮助我!感谢您的帮助!
我有一个 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 时,我注意到单选按钮按预期工作,所以这让我想知道一些事情。
光纤的速度快到我可以编写更错误的代码了吗?
使用更新的 React 版本时,Modal 组件中的生命周期方法有什么不同吗?
setState 有什么不同导致更多的东西用纤维重新渲染吗?
更新
我已经在控制台记录了这个过程,我看到在按下一个项目后,ListView 上的 renderRow 不会再次被调用,而是 SelectedShippingMethod 被选中并被调用undefined
。为什么会发生这种情况,我怎样才能让它工作?