【发布时间】:2019-03-22 03:21:22
【问题描述】:
我正在开发我的第一个 React Native 应用程序,但对 React 和 React Native 感觉很舒服,这让我对这个障碍感到惊讶。
目标 - 允许用户根据输入需求动态创建选项卡。每个选项卡都重复使用相同的组件,即一个表单。按下时,选项卡应显示其相应的表单。表单工作正常。
问题 - 父组件不会在标签按下时呈现正确的表单。状态更新,但组件仍保留在选定的第一个组件上。如果我在一个屏幕上列出表单,一个接一个,我可以看到填写一个表单对其他表单没有影响(期望的效果)。
如果我不渲染表单组件,它会在第一次按标签时工作。这让我想知道 React 是否没有在父组件中注册更改,因为子组件始终是我希望显示的其他子组件的副本。
我以三种方式解决了这个问题,但都没有运气。
创建存储在父组件状态中的组件数组。创建一个新选项卡通过抓取该数组,将一个组件推入其中并使用该新数组重置状态,将表单组件推入当前数组的状态。我将键存储在屏幕按下时更新的状态。该键与组件数组中的索引匹配,以显示所选组件及其相应的选项卡。
使用 componentDidUpdate 在屏幕上设置显示的组件按下类似于上面,但不是在我的渲染函数中键入数组,而是在 componentDidUpdate 函数中手动设置每次更新组件的显示视图并使用它在渲染中。
目前(后面的代码)- 为每个添加的选项卡创建唯一的状态键,以存储相应的组件并使用它来破译要显示的组件。
我决定在一些子组件上放置一个 ref。我在渲染之前使用了 console.log 来查看是否选择了正确的组件进行显示。它显示它是,但它并没有以这种方式出现在屏幕上。我还将被单击的选项卡编号添加到 UI 中,我可以看到我的状态在每次按下选项卡时都会正确更新。
任何帮助将不胜感激。最后的手段我会让用户在到达此视图之前选择他们想要的表单数量并根据该数字创建它,但我不希望这样做。
import React from 'react';
import { connect } from 'react-redux';
import { View, Text, TouchableOpacity } from 'react-native';
import CreateWorkoutSet from './CreateWorkoutSet';
import { Entypo } from '@expo/vector-icons';
class CreateWorkout extends React.Component {
constructor(props) {
super(props)
this.state = {
workoutSetTemplate0: <CreateWorkoutSet navigation={this.props.navigation}/>,
showTab: 0,
totalTabs: 0,
}
this.addWorkoutSetToGroup = this.addWorkoutSetToGroup.bind(this)
}
componentDidMount() {
this.setState({
tabs: [
<TouchableOpacity onPress={() => this.setState({ showTab: 0 })}>
{ this.state.showTab === 0 ? (
<View style={{ backgroundColor: 'red', height: 40, width: 40 }}>
<Text>Tab: 1</Text>
</View>
) :
<View style={{ backgroundColor: 'grey', height: 40, width: 40 }}>
<Text>Tab: 1</Text>
</View>
}
</TouchableOpacity>
],
showTab: 0
})
}
addWorkoutSetToGroup() {
let tabNumber = this.state.totalTabs + 1
let tabKey = `workoutSetTemplate${tabNumber}`
let tabs = this.state.tabs
tabs.push(
<TouchableOpacity onPress={() => this.setState({ showTab: tabNumber })}>
{ this.state.showTab === tabNumber ? (
<View style={{ backgroundColor: 'red', height: 40, width: 40 }}>
<Text>Tab: {tabNumber}</Text>
</View>
) :
<View style={{ backgroundColor: 'grey', height: 40, width: 40 }}>
<Text>Tab: {tabNumber}</Text>
</View>
}
</TouchableOpacity>
)
this.setState({ [tabKey]: <CreateWorkoutSet navigation={this.props.navigation} />, tabs: tabs, totalTabs: tabNumber })
}
render() {
let template = this.state[`workoutSetTemplate${this.state.showTab}`]
let tabs = this.state.tabs
return(
<View style={{flex: 1, justifyContent: 'center', marginTop: 20}}>
<View style={{ flexDirection: 'row' }}>
{tabs}
</View>
<View>
<Text>Add Exercise To Group</Text>
<TouchableOpacity onPress={()=> this.addWorkoutSetToGroup()}>
<Entypo name='circle-with-plus' size={36} color='red' />
</TouchableOpacity>
</View>
<TouchableOpacity onPress={() => this.props.navigation.navigate('BlockDetail')}>
<Text>Blocks</Text>
</TouchableOpacity>
<Text>{this.state.showTab}</Text>
{template}
</View>
)
}
}
export default connect()(CreateWorkout)
【问题讨论】:
标签: reactjs react-native