Basit
Basit

Reputation: 367

How to change JavaScript array of objects' property in react native

I am rendering couple of boxes using Flatlist. The box will be blank if the "shapes" element's (property) "visible" key is false, which is defined is state. I don't know if its the right way to do so.

Now I want when I click box (that is wrapped in touchableOpacity) visible value changes to true and icon appear on box.

I can't figure it out to do so. I don't know should I define visible property in state or add it later dynamically.

Here is my code

const { width, height } = Dimensions.get('window')

class App extends Component {
   state = {
      shapes: [
         { id: 1, icon: 'home', color: 'green', visible: false },
         { id: 2, icon: 'creditcard', color: 'red', visible: false },
         { id: 3, icon: 'star', color: 'purple', visible: true },
         { id: 3, icon: 'notification', color: 'blue', visible: false },
      ]
   }

   showShapes = () => {
      for (let e of this.state.shapes) {
         e.visible = true
         console.log(e.visible)
      }
      this.setState({
         // what to write here
      })
   }

   renderItems = ({ item }) => {
      return (
         <TouchableOpacity
            activeOpacity={0.6}
            onPress={this.showShapes}
            style={{ padding: 10, backgroundColor: '#ccc', margin: 15, width: width / 4 }}
         >
            {item.visible && <Icon
               name={item.icon} color={item.color} size={50}
            /> }
         </TouchableOpacity>
      )
   }


   render() {
      return (
         <Fragment>
            <FlatList
               numColumns='2'
               data={this.state.shapes}
               renderItem={this.renderItems}
               keyExtractor={(item) => item.id.toString()}
            />
         </Fragment>
      )
   }
}

Hope I am clear.

Upvotes: 0

Views: 388

Answers (2)

Govan
Govan

Reputation: 1379

first in renderItem you should pass the index like this

renderItems = ({ item,index }) => {
      return (
         <TouchableOpacity
            activeOpacity={0.6}
            onPress={()=>this.showShapes(index)}
            style={{ padding: 10, backgroundColor: '#ccc', margin: 15, width: width / 4 }}
         >
            {item.visible && <Icon
               name={item.icon} color={item.color} size={50}
            /> }
         </TouchableOpacity>
      )
   }

then in showshapes do like this

showShapes = index => {
     let shapes = [ ...this.state.shapes ];
     this.state.shapes.map((shape,key)=>{
       if(shape.id==shapes[index].id){
           shapes[key]={...shapes[key], visible: true};
   }else{
     shapes[key]={...shapes[key], visible: false};

   }
 })

Upvotes: 0

Dupocas
Dupocas

Reputation: 21307

You are doing it right! Define in your state the visible property, handle the click like this:

const handleBoxClick = boxId => this.setState(state =>({
    shapes : state.shapes.map((x,i) =>{
        if(x.id !== boxId) return x
        return {...x, visible: !state.shapes[i].visible}
    })
}))

And now use conditional render to hide those boxes that aren't visible:

return <>{box.visible && <Box box={box} />} </>

Upvotes: 3

Related Questions