0

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.

2 Answers 2

3

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} />} </>
Sign up to request clarification or add additional context in comments.

Comments

0

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};

   }
 })

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.