首页 > 解决方案 > 如何引用映射数组的单个元素来呈现视图

问题描述

我有一个对象数组。我把它映射成一个带有标签和图标按钮的列表。当我点击按钮时,我需要在该行的元素下方显示另一个视图。

对象数组是一个 let 变量。我想把它作为一个状态(因为在执行函数 setState 时重新渲染),但我需要它作为一个 let 变量,因为它们是来自导航路线的数据

我的想法是在数组的每个对象中添加一个标志,以指示何时必须渲染视图。这在开始时是错误的,当我按下按钮时是真的,但什么也没发生。如果在我点击按钮时不使用标志,则视图会在每一行中呈现

state={
   visible:false
}

getNewView = (item) => {
        if (this.state.visible && item.showViewBelow)
            return (
                <View>
                    <HiddenViewComponent/>
                </View>
            )
};

btnHandler = (item) => {
   item.showViewBelow = true;
   this.setState({visible:true})
}


render(){
   const {navigation} = this.props;
   const arrayNav = navigation.getParam('data', '');

   let array = [
            {
                id:'0',
                label: arrayNav.label1,
                showViewBelow: false
            },
            {
                id:'1',
                label: arrayNav.label2,
                showViewBelow: false
            },
            {
                id:'2',
                label: arrayNav.label3,
                showViewBelow: false
            }
   ]
return(
  <View>
     array.map((item, key)=> { return

         <View key = {key} style={{marginHorizontal: 25}}>

              <Text>{item.label}</Text>

              <TouchableOpacity onPress={this.btnHandler(item)}>
                 <Image source=(blablabla)/>
              </TouchableOpacity>

              {this.getNewView(item)}

         </View>)

     )}
  </View>
)
 }

因此,当我单击列表的一行时,我希望在此行下方显示一个新视图。

我试图将其中一个对象中的标志切换为真,而在其他对象中将其设置为假。它在那条线上工作得很好!当我单击该行中的按钮时,新视图会正确呈现在该行下方。

我还尝试使用 Flatlist,并在新视图返回后将一些带有状态变量的额外数据用 setState 进行更新。(只是尝试重新渲染页面)。

尽管如此,我还是尝试将 this.forceUpdate() 放在 getNewView 方法中。什么都没发生。什么都没有渲染

所以我认为问题是我没有重新渲染整个屏幕,因为将对象作为 let 变量,这不会发生。

有什么想法吗?

标签: javascripttypescriptreact-native

解决方案


您可以在常量实用程序中创建方法来定义 defaultArray,例如

getDefaultArray(arrayNav){

    return [
        {
            id:'0',
            label: arrayNav.label1,
            showViewBelow: false
        },
        {
            id:'1',
            label: arrayNav.label2,
            showViewBelow: false
        },
        {
            id:'2',
            label: arrayNav.label3,
            showViewBelow: false
        }
   ];

}

在您的组件代码中

import Constants from "./Constants"

ComponentDidMount(){

    const {navigation} = this.props;
    const arrayNav = navigation.getParam('data', '');

    this.state={
        visible:false,
        array = Constants.getDefaultArray(arrayNav);
    }
}

getNewView = (item) => {
        if (this.state.visible && item.showViewBelow)
            return (
                <View>
                    <HiddenViewComponent/>
                </View>
            )
};

btnHandler = (item, index) => {

   const {navigation} = this.props;
   const arrayNav = navigation.getParam('data', '');

   let newData = Constants.getDefaultArray(arrayNav);
   newData[index].showViewBelow = true;
   this.setState({visible:true , array:newData})
}

render(){

    return(
      <View>
         this.state.array.map((item, key)=> { return

             <View key = {key} style={{marginHorizontal: 25}}>

                  <Text>{item.label}</Text>

                  <TouchableOpacity onPress={this.btnHandler(item,key)}>
                     <Image source=(blablabla)/>
                  </TouchableOpacity>

                  {this.getNewView(item)}

             </View>)

         )}
      </View>
    )
 }

推荐阅读