5

I have been on this for a little while and here is whats going on. I have an array in mobx Storage that I Would like to display in a collapsable view within a Flatlist in my React native component. The problem here is that when I click on it it does change the state but the action does not take place. After some research, I found an Accordion in NativeBase and tried implementing it after a successful small test. Unfortunately, it does not recognize indexed values from the array saying that it is not an object. So the first issue is related to the action of closing and opening the collapsable in relation to a mobx action, the second is an accordion that is unable to read indexed values from the array. If anyone can help find a way to have a dynamic collapsable for the concerned objects within the array as well as display the values, that would be great.

Below are the concerned shunk of code, if you need more please feel free to ask, Thank you for your time!

mobx file:

import {observable, action} from 'mobx';
import {LayoutAnimation} from 'react-native'

class StateStorage {



  @observable list= ['Category','','','']
  @observable selectedMaterial=''
  @observable  materials = [ 
       {

      Specs:[
        textCategory= 'Drain',
        textSpec1='Usabley',
        textSpec2='Healthy',
        textSpec3='Bio'],
        name: 'RYTT',
        price: '$',
        image: require("./Icons/Rain.jpg"),
        spec1:require("./Icons/friendly.png"),
        spec2:require("./Icons/Cutler.png"),
        spec3:require("./Icons/logout.png"),
        category:'',
        icon: '',
      uses:[
              uses1='cecec', 
              uses2='- Cans' ,
              uses3='- Jars',
              uses4='- Signages',

      pros:[
              pros1='Lightweight',
              pros2='Tough',
              pros3='xsxxs',
              pros4='cdccd',
              ],
         cons:[         
              cons1='Inflated',
              cons2='Can be sticky',
              cons3='ejhcejccjhc',
              cons4='dcd',
              cons5='dc'],
        expanded: true,
           specCount:0,
            userCount:0,
             prosCount:0,
              consCount:0,                                                            
                x:0

    },   
    {

      Specs:[
        textCategory= 'Drain',
        textSpec1='Usabley',
        textSpec2='Healthy',
        textSpec3='Bio'],
        name: 'RYTT',
        price: '$',
        image: require("./Icons/Rain.jpg"),
        spec1:require("./Icons/friendly.png"),
        spec2:require("./Icons/Cutler.png"),
        spec3:require("./Icons/logout.png"),
        category:'',
        icon: '',
      uses:[
              uses1='cecec', 
              uses2='- Cans' ,
              uses3='- Jars',
              uses4='- Signages',

      pros:[
              pros1='Lightweight',
              pros2='Tough',
              pros3='xsxxs',
              pros4='cdccd',
              ],
         cons:[         
              cons1='Inflated',
              cons2='Can be sticky',
              cons3='ejhcejccjhc',
              cons4='dcd',
              cons5='dc'],
        expanded: true,
           specCount:0,
            userCount:0,
             prosCount:0,
              consCount:0,                                                            
                x:0

    },
     {

      Specs:[
        textCategory= 'Drain',
        textSpec1='Usabley',
        textSpec2='Healthy',
        textSpec3='Bio'],
        name: 'RYTT',
        price: '$',
        image: require("./Icons/Rain.jpg"),
        spec1:require("./Icons/friendly.png"),
        spec2:require("./Icons/Cutler.png"),
        spec3:require("./Icons/logout.png"),
        category:'',
        icon: '',
      uses:[
              uses1='cecec', 
              uses2='- Cans' ,
              uses3='- Jars',
              uses4='- Signages',

      pros:[
              pros1='Lightweight',
              pros2='Tough',
              pros3='xsxxs',
              pros4='cdccd',
              ],
         cons:[         
              cons1='Inflated',
              cons2='Can be sticky',
              cons3='ejhcejccjhc',
              cons4='dcd',
              cons5='dc'],
        expanded: true,
           specCount:0,
            userCount:0,
             prosCount:0,
              consCount:0,                                                            
                x:0

    },
]

@action incrementSpecCount(){
//x=uses1 or x=pros1 oe x=cons1

for (i = 0; i < this.materials.length; i++)

{
for (n=0; n<this.materials[i].Specs.length; n++){
if(this.materials[i].Specs[n]==='')
{this.materials[i].specCount++,
this.materials[i].x=i+1}}

}

}


@action incrementUserCount(){
//x=uses1 or x=pros1 oe x=cons1

for (i = 0; i < this.materials.length; i++)

{
for (n=0; n<this.materials[i].uses.length; n++){
if(this.materials[i].uses[n]==='')
{this.materials[i].userCount++,
this.materials[i].x=i+1}}

}

}


@action incrementProsCount(){
//x=uses1 or x=pros1 oe x=cons1

for (i = 0; i < this.materials.length; i++)

{
for (n=0; n<this.materials[i].pros.length; n++){
if(this.materials[i].pros[n]==='')
{this.materials[i].prosCount++,
this.materials[i].x=i+1}}

}

}
@action incrementConsCount(){
//x=uses1 or x=pros1 oe x=cons1

for (i = 0; i < this.materials.length; i++)

{
for (n=0; n<this.materials[i].cons.length; n++){
if(this.materials[i].cons[n]==='')
{this.materials[i].consCount++,
this.materials[i].x=i+1}}

}

}

@action changeLayout(index) {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
this.materials[index].expanded= !this.materials[index].expanded
console.log(this.materials[index].expanded)
}

React file with customized collapsable (I have removed styling positions and other values except for display due to character limit):

import React, { Component } from 'react';
import { View, Text, FlatList, Image, ImageBackground, PixelRatio, Platform, UIManager, TouchableOpacity, LayoutAnimation } from 'react-native';
import {widthPercentageToDP as wp, heightPercentageToDP as hp} from 'react-native-responsive-screen'
import DropDownItem from 'react-native-drop-down-item';
import StateStorage from '../StateStorage';
import {observer} from 'mobx-react';
import { Container, Header, Content, Accordion } from "native-base";


class App extends Component {

    constructor (props) {
    super(props)
       if (Platform.OS === 'android') {
      UIManager.setLayoutAnimationEnabledExperimental(true);
    }

      }


  componentDidMount(index){
    console.log(StateStorage.materials[0].x)
    console.log(StateStorage.materials[0].prosCount)
  }





SpecViewStyle(index){

  StateStorage.incrementSpecCount()

  if(StateStorage.materials[index].specCount=== StateStorage.materials[index].x*0)

  {return {height:PixelRatio.get()<=2 && Platform.OS==='android' ? 200 : 260}}

  else if(StateStorage.materials[index].specCount=== StateStorage.materials[index].x)

  {return {height:PixelRatio.get()<=2 && Platform.OS==='android' ? 185 : 200}}

  else if(StateStorage.materials[index].specCount=== StateStorage.materials[index].x*2)

  {return{height:PixelRatio.get()<=2 && Platform.OS==='android' ? 165 : 150}}

  else if(StateStorage.materials[index].specCount=== StateStorage.materials[index].x*3)

  {return{height:PixelRatio.get()<=2 && Platform.OS==='android' ? 130 : 120}}




}



CommonUseViewStyle(index){

StateStorage.incrementUserCount()

if(StateStorage.materials[index].userCount=== StateStorage.materials[index].x*0)

{return {height:PixelRatio.get()<=2 && Platform.OS==='android' ? 200 : 190}}

else if(StateStorage.materials[index].userCount=== StateStorage.materials[index].x)

{return {height:PixelRatio.get()<=2 && Platform.OS==='android' ? 185 : 175}}

else if(StateStorage.materials[index].userCount=== StateStorage.materials[index].x*2)

{return{height:PixelRatio.get()<=2 && Platform.OS==='android' ? 165 : 150}}

else if(StateStorage.materials[index].userCount=== StateStorage.materials[index].x*3)

{return{height:PixelRatio.get()<=2 && Platform.OS==='android' ? 130 : 120}}

else if(StateStorage.materials[index].userCount=== StateStorage.materials[index].x*4)

{return{height:PixelRatio.get()<=2 && Platform.OS==='android' ? 110 : 100}}

else if(StateStorage.materials[index].userCount=== StateStorage.materials[index].x*5)

{return{height:PixelRatio.get()<=2 && Platform.OS==='android' ? 75 :65}}

else if(StateStorage.materials[index].userCount=== StateStorage.materials[index].x*6)

{return{height:PixelRatio.get()<=2 && Platform.OS==='android' ? 37.5 : 31}}

else if(StateStorage.materials[index].userCount=== StateStorage.materials[index].x*10
  || StateStorage.materials[index].userCount=== StateStorage.materials[index].x*9
  || StateStorage.materials[index].userCount=== StateStorage.materials[index].x*8
  ||StateStorage.materials[index].userCount=== StateStorage.materials[index].x*7

 )
{return {height:25}}

else {return{height:PixelRatio.get()<=2 && Platform.OS==='android' ? 167.5 : 45}}

}



ProsViewStyle(index){
  StateStorage.incrementProsCount()


  if(StateStorage.materials[index].prosCount=== StateStorage.materials[index].x*0)

{return {height:PixelRatio.get()<=2 && Platform.OS==='android' ? 200 : 190}}

else if(StateStorage.materials[index].prosCount=== StateStorage.materials[index].x)

{return {height:PixelRatio.get()<=2 && Platform.OS==='android' ? 185 : 175}}

else if(StateStorage.materials[index].prosCount=== StateStorage.materials[index].x*2)

{return{height:PixelRatio.get()<=2 && Platform.OS==='android' ? 165 : 150}}

else if(StateStorage.materials[index].prosCount=== StateStorage.materials[index].x*3)

{return{height:PixelRatio.get()<=2 && Platform.OS==='android' ? 130 : 120}}

else if(StateStorage.materials[index].prosCount=== StateStorage.materials[index].x*4)

{return{height:PixelRatio.get()<=2 && Platform.OS==='android' ? 110 : 100}}

else if(StateStorage.materials[index].prosCount=== StateStorage.materials[index].x*5)

{return{height:PixelRatio.get()<=2 && Platform.OS==='android' ? 75 :65}}

else if(StateStorage.materials[index].prosCount=== StateStorage.materials[index].x*6)

{return{height:PixelRatio.get()<=2 && Platform.OS==='android' ? 37.5 : 31}}

else if(StateStorage.materials[index].prosCount=== StateStorage.materials[index].x*8
  || StateStorage.materials[index].prosCount=== StateStorage.materials[index].x*7

 )
{return {height:25}}

  }

 ConsViewStyle(index){
    StateStorage.incrementConsCount()


    if(StateStorage.materials[index].consCount=== StateStorage.materials[index].x*0)

  {return {height:PixelRatio.get()<=2 && Platform.OS==='android' ? 200 : 190}}

  else if(StateStorage.materials[index].consCount=== StateStorage.materials[index].x)

  {return {height:PixelRatio.get()<=2 && Platform.OS==='android' ? 185 : 175}}

  else if(StateStorage.materials[index].consCount=== StateStorage.materials[index].x*2)

  {return{height:PixelRatio.get()<=2 && Platform.OS==='android' ? 165 : 150}}

  else if(StateStorage.materials[index].consCount=== StateStorage.materials[index].x*3)

  {return{height:PixelRatio.get()<=2 && Platform.OS==='android' ? 130 : 120}}

  else if(StateStorage.materials[index].consCount=== StateStorage.materials[index].x*4)

  {return{height:PixelRatio.get()<=2 && Platform.OS==='android' ? 110 : 100}}

  else if(StateStorage.materials[index].consCount=== StateStorage.materials[index].x*5)

  {return{height:PixelRatio.get()<=2 && Platform.OS==='android' ? 75 :65}}


    else {return {height:PixelRatio.get()<=2 && Platform.OS==='android' ? 200 : 190}}
 }

       render() {





    return (
      // Remain Category image and CSS
      // add search bar
      <View
      style={{
        backgroundColor:'#262A2C',
        flex:1
      }}>
      <FlatList
     style={{marginTop:80,}}
     //ListHeaderComponent=
     //if slow change initialNumToRender and count algorithm for use,pros and cons high
     /*onEndReachedThreshold={2}
     onEndReached={({ distanceFromEnd }) => {
       console.log('on end reached ', distanceFromEnd)
     }}*/
     windowSize={StateStorage.materials.length+4}
     initialNumToRender={StateStorage.materials.length}


        data={StateStorage.materials}
        renderItem={({ item, index }) => (
       <View>
         <TouchableOpacity
         onPress={() =>{
           StateStorage.chooseMaterial(index),
           console.log(StateStorage.materials[index].count),
            console.log(StateStorage.materials.length)  ,
            console.log(StateStorage.materials[0].x)




         }}>
          <ImageBackground
        // read computed                   
          source={item.image} 
        //pay FlatIcon or design personal one
          style={{ 

            resizeMode: 'cover',
           //resizeMode: 'contain,
          position:'relative',

          width: wp('100%'), 
          left: wp('0%'),
          borderBottomWidth: 1,
          borderBottomColor: 'grey',
          padding: hp('6%'),
          }}
        >
       <View
            style={{
              flex:1,
              height: null,

             width: null,


              borderBottomColor: 'grey',

            }}>


               <Image
               style={{
               width:wp('10%'),
               height:hp('5%'),
               left:wp('-10%'),
               top:hp('-5.5%'),

               }}
               source={item.spec1}/>
              <Image
               style={{
               width:wp('10%'),
               height:hp('5.5%'),
               left:wp('-10%'),
               top:hp('0%'),

               }}
               source={item.spec2}/>

               <Image
               style={{
               width:wp('10%'),
               height:hp('5.5%'),
               left:wp('-10%'),
               top:hp('6%'),

               }}
               source={item.spec3}/>

              <Text 
              style={{ fontWeight: 'bold',
               fontSize: 22, 
              left:item.name.length<=5 ? wp('32.5%'):wp('27.5%'),
               top:hp('-9.5%'),


               }}>
               {item.name}
               </Text>
              <Text
              style={{
                fontWeight: 'bold',
                fontSize: 25, 
                top: hp('-25%'),
                left:wp('80%')

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


          </View>






   </ImageBackground>
   </TouchableOpacity>
   <TouchableOpacity activeOpacity={0.8}  
   onPress={() => {

             StateStorage.changeLayout(index)
             console.log(StateStorage.materials[index].expanded)
              }} 

    style={{ padding: 10,

    backgroundColor:'black',

    left:wp('-10.9%'),
    top:hp('0%'),
    width: wp('120%'),
    height:hp('5%')}}>
   <Image
               style={{
               width:wp('9%'),
               height:hp('4.5%'),
              tintColor:'white',
              left:250,
              top:-10

               }}
               source={StateStorage.materials[index].expanded ? require('../Icons/arrowDown.png') : require('../Icons/arrowUp.png') }/>
</TouchableOpacity>

<View style={{height: StateStorage.materials[index].expanded ? null : 0,
      overflow: 'hidden', 
      backgroundColor:'black' }}>
            <Text 
            style={{
               fontSize: 17,
               left:150,
               top:-10,
               color: 'turquoise',
               padding: 10}}>
          Specs
            </Text>
            <View style={this.SpecViewStyle(index)}>
            <View style={{
             display:item.Specs[0]==='' ? 'none' : 'flex',
            }} >
            <Image
             style={{
             display: item.Specs[0]==='' ? 'none' : 'flex',
            }}
              source={item.spec3}/> 
            <Text
             style={{

              display:item.Specs[0]==='' ? 'none' : 'flex',
      }}>
{item.Specs[0]}

            </Text>
            </View>
            <View style={{
              display:item.Specs[1]==='' ? 'none' : 'flex',


          }}>
             <Image

             style={{width:wp('8.5%'),
             height:PixelRatio.get()<= 2  ? hp('5.5%') : hp('4%'),
             display: item.Specs[1]==='' ? 'none' : 'flex',
             marginBottom: 15,
            tintColor:'white'}}

              source={item.spec1}/> 
            <Text
             style={{

              display: item.Specs[1]==='' ? 'none' : 'flex',
             }}>
{item.Specs[1]}
            </Text>
            </View>
            <View style={{
              display:item.Specs[2]==='' ? 'none' : 'flex',


          }}>
            <Image
             style={{
             display: item.Specs[2]==='' ? 'none' : 'flex',
          }}
              source={item.spec2}/> 
            <Text
             style={{

              display: item.Specs[2]==='' ? 'none' : 'flex',
             }}>
{item.Specs[2]}
            </Text>
            </View>
            <View style={{
              display:item.Specs[3]==='' ? 'none' : 'flex',


          }}>
            <Image

             display: item.Specs[3]==='' ? 'none' : 'flex',
             }}
              source={item.spec3}/> 
            <Text
             style={{
              ,
              display:item.Specs[3]==='' ? 'none' : 'flex',
              }}>
{item.Specs[3]}

            </Text>
        </View>
            <Image 
            //category implementation
            />

            <Text>


            </Text>
            </View>

            <Text 
            style={{
              fontSize: 17 ,
               left:125,
               top:-90,
               color: 'turquoise',
               paddingTop: PixelRatio.get()<= 2 && Platform.OS ===' android' ? 55 :65,
               paddingBottom: 10}}>
          Common uses
            </Text>
            <View style={     
              this.CommonUseViewStyle(index)


            }>

            <Text

            style=
             {{       



             }}>
{item.uses[0]}
            </Text>
            <Text
             style={{


              display:item.uses[1]==='' ? 'none' : 'flex', 

 }

               }
              >
{item.uses[1]}
            </Text>
            <Text
             style={{



              display:item.uses[2]==='' ? 'none' : 'flex',



              } }
              >
{item.uses[2]}
            </Text>
            <Text
             style={{

              display:item.uses[3]==='' ? 'none' : 'flex',



              } }
              >
{item.uses[3]}
            </Text>

            </View>

          <Text
          style={{


          }}>
Pros 
          </Text>
          <View
          style={
            this.ProsViewStyle(index)
          }>


          <Image
          style={{

            display: item.pros[0]==='' ? 'none':'flex',

          }}
          source = {require('../Icons/plus.png')}/>
          <Text
          style={{

            display: item.pros[0]==='' ? 'none':'flex',

          }}
          >
{item.pros[0]}
          </Text>

         <Image
          style={{
            display: item.pros[1]==='' ? 'none':'flex',

          source = {require('../Icons/plus.png')}/>
           <Text
          style={{

            display: item.pros[1]==='' ? 'none':'flex',


          }}>
{item.pros[1]}
          </Text>
          <Image
          style={{
            display: item.pros[2]==='' ? 'none':'flex',

          }}
          source = {require('../Icons/plus.png')}/>
           <Text
          style={{

            display: item.pros[2]==='' ? 'none':'flex',


          }}>
{item.pros[2]}
          </Text>
          <Image
          style={{
            display: item.pros[3]==='' ? 'none':'flex',

          }}
          source = {require('../Icons/plus.png')}/>
           <Text
          style={{

            display: item.pros[3]==='' ? 'none':'flex',


          }}>
{item.pros[3]}
          </Text>

            </View>

            <Text
          style={{
              fontSize: 17 ,
                left:168,
                top:-35,
                marginTop:70,
                color: 'turquoise',
                paddingTop: PixelRatio.get()<= 2 && Platform.OS ===' android' ? 55 :65,
                paddingBottom: 10



          }}>
Cons
          </Text>
            <View style={
           this. ConsViewStyle(index)


            }>
            <View
            style={{
              display:item.cons[0]==='' ? 'none' : 'flex',


          }}>
            <Image
          style={{

            display: item.cons[0]==='' ? 'none':'flex',

          }}
          source = {require('../Icons/minus.png')}/>
           <Text
          style={{

            display: item.cons[0]==='' ? 'none':'flex',

          }}
          >
{item.cons[0]}
          </Text>
          </View>
          <View
          style={{
            display:item.cons[1]==='' ? 'none' : 'flex',


        }}>
          <Image
          style={{

            display: item.cons[1]==='' ? 'none':'flex',

          }}
          source = {require('../Icons/minus.png')}/>
        <Text
          style={{
           ,
            display: item.cons[1]==='' ? 'none':'flex',


          }}>
{item.cons[1]}
          </Text>
          </View>
          <View
          style={{
            display:item.cons[2]==='' ? 'none' : 'flex',


        }}>
        <Image
          style={{

            display: item.cons[2]==='' ? 'none':'flex',

          }}
          source = {require('../Icons/minus.png')}/>
        <Text
          style={{

            display: item.cons[2]==='' ? 'none':'flex',
         10,
            left:60

          }}>
{item.cons[2]}
          </Text>
          </View>
          <View
          style={{
            display:item.cons[3]==='' ? 'none' : 'flex',


        }}>
          <Image
          style={{

            display: item.cons[3]==='' ? 'none':'flex',

          }}
          source = {require('../Icons/minus.png')}/>
        <Text
          style={{
           ,
            display: item.cons[3]==='' ? 'none':'flex',


          }}>
{item.cons[3]}
          </Text>
          </View>
          <View
          style={{
            display:item.cons[4]==='' ? 'none' : 'flex',


        }}>
          <Image
          style={{

            display: item.cons[4]==='' ? 'none':'flex',

          }}
          source = {require('../Icons/minus.png')}/>
        <Text
          style={{

            display: item.cons[4]==='' ? 'none':'flex',


          }}>
{item.cons[4]}
          </Text>
          </View>
            </View>
            </View>
          </View>  

        )}
      />
      </View>
    );
  }
}



  export default App

For the Accordion its the same code just that rather than:

it is replaced with:

<Content>
          <Accordion dataArray={StateStorage.materials} expanded={null}
          animation={true}
             renderContent={({ item, index }) => ( ..(displayed code)... )}>
            </Text>)}/>
        </Content>
Camille Basbous
  • 299
  • 5
  • 11
  • 34

1 Answers1

0

Not sure of your flexibility but i would highly recommend you to switch to using react-native-paper instead of native-base

You can use this component and i believe it work for you.

These are different applications of their accordion list component

Hope this Helps!

Abdeen
  • 922
  • 9
  • 30
  • Hi Abdeen, I have no problem when it comes to flexibility here, but this doesn't solve the problem, unfortunately, thanks for trying though – Camille Basbous Oct 04 '19 at 20:32