React Native-在for循环中一个接一个地打开多个模态

时间:2019-03-09 14:35:24

标签: javascript reactjs react-native for-loop react-modal

我首先进行Ajax调用(对API),该调用向我提供一些数据,成就列表(对象数组)。我想遍历此数组,将第一个成就显示为模态,然后单击按钮关闭模态,然后显示下一个(下一个成就),依此类推。

提供数据的Ajax调用:

print(comp(x_real.x))
print(comp(0.7851167))

在此显示模式:

[  1.31290960e-08]
6.151420706146382e-09

此刻所有模态同时打开。单击“收集”按钮后,如何一个接一个地打开它们?

2 个答案:

答案 0 :(得分:0)

问题是您的页面上有多个模式,并且它们都使用相同的布尔值来检查是否应该渲染它们。最初, showAchievementModal 设置为true,因此将渲染所有模态。此外,在 closeModal 中将 showAchievementModal 设置为false后,它将永久保持为false,因此不会呈现其他模态。

render() {
    return (
        {this.state.showAchievementModal &&
          <Modal
             ...          
          </Modal>
        }
    )
}

您应该跟踪有效模式的索引,而不是 showAchievementModal 。因此,从API获取成就列表后,请将 activeModalIndex 设置为 0 。用户关闭第一个模态后,将 closeModal 方法内的 activeModalIndex 设置为 1 ,然后将其设置为 2 关闭第二个模式后,依此类推。

现在,对于每个与单个成就相对应的模态,我们必须将成就数组中的每个元素映射到一个模态,并且仅在其对应的索引为活动索引时才有条件地渲染它。

render() {
    const achievements = this.props.store.achievements;
    const { activeModalIndex } = this.state;

    return achievements.map((data, index) => activeModalIndex === index &&
      <Modal key={index}>
        <View>
          <View style={styles.container}>
            <Text>{data.title}</Text>
            <Text>{data.description}</Text>

            <TouchableOpacity onPress={this.closeModal}>
              <Text>Collect</Text>
            </TouchableOpacity>
          </View>
        </View>
      </Modal>
    )
}

当用户关闭当前活动的模态时,只需增加活动模态的索引,下一个模态就会出现,而不是当前的模态。如果新的递增值等于或大于数组长度,则不会呈现任何内容,因此无需在设置新状态之前检查最大索引值。

closeModal = () => {   
    this.setState(previousState => ({
      activeModalIndex: previousState.activeModalIndex + 1,
    }))
}

此外,渲染列表时,请阅读有关the dangers of setting index as key的信息。如果您碰巧需要按某个值/优先级对成就进行排序,并且用户可以检索其成就的多个页面,则可能会导致呈现错误的组件。

答案 1 :(得分:0)

这是我有效的代码的更新版本:

在构造函数中初始化activeModalIndex:

constructor(props) {
  super(props)

  this.state = {
    activeModalIndex: 0
  }
}

获得成就:

getAchievements = () => {
  if(this.props.store.achievements.length > 0) {
    this.setState({
      showAchievementModal: true,
      activeModalIndex: 0,
    })
  }
}

渲染功能:

 render() {
   return this.props.store.achievements.map((data,index) => this.state.activeModalIndex === index &&
     <Modal>
       <View key={index}>
         <View style={styles.container}>
           <Text>{data.title}</Text>
           <Text>{data.description}</Text>

           <TouchableOpacity onPress={this.closeModal}>
             <Text>Collect</Text>
           </TouchableOpacity>
        </View>
      </View>
    </Modal>
  )
}

关闭模式:

closeModal = () => {
  const maxIndex = this.props.store.achievements.length - 1
  const currentIndex = this.state.activeModalIndex
  const isLastModal = currentIndex === maxIndex
  const newIndex = isLastModal? -1: currentIndex +1

  this.setState({
    activeModalIndex: newIndex
  })
}