简体   繁体   中英

React How to use different states with click event

In short: I'm implementing Simon-Says game app in React Native. (user sees a sequence of flashing buttons, needs to press the buttons in the correct order).

I want to know how to use 2 different states in TouchableOpacity, one of them as a condition to press the button, one for changing the style of the button, and also being notified for this specific press.

So,

I'm having a problem to implement the playerTurn(), because I'm not sure how to pass the canPress state to the TouchableOpacity button, considering I'm passing style state that changes in compTurn() (function that shows a sequence of flashing buttons - then computer turn's over) In the player turn, things I need to consider:

  1. after the state canPress changes, the user will be allowed to press on the buttons
  2. user presses one of the 4 buttons
  3. the method playerTurn() will be notified which button did the player pressed. (I'm asking how can I get that notification from the button to the method?) after that, I can push it's choice to the playerSeq array (if pressed green - pushes 1, etc) and call function that changes the style state (greenFlash for example)

code in short :

export default class App extends Component{ 
  constructor (props){
    super(props);
    this.seq=[1,2,3,1,4] //will be random, this is just for testing
    this.playerSeq=[] 
    ...
    this.state = {
      canPress: false,
      greenB: {
        backgroundColor: 'darkgreen'
      }, ...

  playerTurn(){
    this.setState({canPress: true})
    // if the user pressed on the green button, then I push 1 to the playerSequence
    // More functionality will be here
  }


  render(){
    return (..
    <TouchableOpacity style={[styles.greenB, this.state.greenB]}></TouchableOpacity> 
//I ALSO WANT TO PASS THE STATE CANPRESS + NOTIFY PLAYERTURN() THAT THE USER PRESSED ON THIS BUTTON

Full code: (not the full game, note that I'm learning react just in the past few days)

export default class App extends Component{ 
  constructor (props){
    super(props);
    this.flash=0
    this.round=1
    this.seq=[1,2,3,1,4] //will be random, this is just for testing
    this.playerSeq=[] 
    this.win=false
    this.ok=true
    this.score=0

    this.state = {
      canPress: false,
      greenB: {
        backgroundColor: 'darkgreen'
      },
      yellowB: {
        backgroundColor: 'orange'
      },
      blueB: {
        backgroundColor: 'blue'
      },
      redB: {
        backgroundColor: 'red'
      }
    }
    this.play=this.play.bind(this)
    this.greenFlash=this.greenFlash.bind(this)
    this.blueFlash=this.blueFlash.bind(this)
    this.redFlash=this.redFlash.bind(this)
    this.playerTurn=this.playerTurn.bind(this)
  }

  play(){
    this.flash=0
    this.round=1 //round will increase, this is just for test
    this.win=false
    this.ok=true
    this.score=0
    this.compTurn();
    this.playerTurn();
  }

  playerTurn(){
    this.setState({canPress: true})

  }
  compTurn() {
      let intervalId = setInterval(()=> {
        if (this.flash==this.round) {
          clearInterval(intervalId);
        }
        else {
          if (this.seq[this.flash]==1){
            this.greenFlash();
          }
          if (this.seq[this.flash]==2){
            this.yellowFlash();
          }
          if (this.seq[this.flash]==3){
            this.blueFlash();
          }
          if (this.seq[this.flash]==4){
            this.redFlash();
          }
          this.flash++;
        }
      }
      , 1500);  
    }

  greenFlash(){
      setTimeout(() => {
        this.setState( {
            greenB:{
              ...this.state.style1, backgroundColor: 'lightgreen'
            }
            })
        }, 200);
      setTimeout(() => {
        this.setState( {
            greenB:{
              ...this.state.style1, backgroundColor: 'darkgreen'
            }
            })
        }, 1000);
    } 

  yellowFlash(){
    setTimeout(() => {
      this.setState( {
          yellowB:{
            ...this.state.style1, backgroundColor: 'yellow'
          }
          })
      }, 200);
    setTimeout(() => {
      this.setState( {
          yellowB:{
            ...this.state.style1, backgroundColor: 'orange'
          }
          })
        }, 1000);
   }

  blueFlash(){
    setTimeout(() => {
      this.setState( {
          blueB:{
            ...this.state.style1, backgroundColor: 'lightblue'
          }
          })
      }, 200);
    setTimeout(() => {
      this.setState( {
          blueB:{
            ...this.state.style1, backgroundColor: 'blue'
          }
          })
        }, 1000);
   }

  redFlash(){
    setTimeout(() => {
      this.setState( {
          redB:{
            ...this.state.style1, backgroundColor: 'pink'
          }
          })
      }, 200);
    setTimeout(() => {
      this.setState( {
          redB:{
            ...this.state.style1, backgroundColor: 'red'
          }
          })
        }, 1000);
   }

  render(){
    return (
      <View>
        <TouchableOpacity style={styles.playB}
        onPress={this.play}> 
        <Text style={{
          color:'white',
          height: 30,
          width:60,
          }}>START</Text>
        </TouchableOpacity>
        <TouchableOpacity style={[styles.greenB, this.state.greenB]}></TouchableOpacity>
        <TouchableOpacity style={[styles.yellowB, this.state.yellowB]}></TouchableOpacity>
        <TouchableOpacity style={[styles.blueB, this.state.blueB]}></TouchableOpacity>
        <TouchableOpacity style={[styles.redB, this.state.redB]}></TouchableOpacity>
    </View>
    );
  }
}

const styles = StyleSheet.create({
  greenB:{
    padding: 5,
    height: 80,
    width: 80,  
    borderRadius:160,    
  },
  yellowB:{
    padding: 5,
    height: 80,
    width: 80,  
    borderRadius:160,    
  },
  blueB:{
    padding: 5,
    height: 80,
    width: 80,  
    borderRadius:160,    
  },
  redB:{
    padding: 5,
    height: 80,
    width: 80,  
    borderRadius:160,    
  },
  playB:{
    alignSelf: 'center',
    backgroundColor: 'blue',
  }

});

Looks like you want to enable clicking on the buttons if state.canPress = true right? Then upon clicking, you wish to notify by calling playerTurn() ?

  1. You can do something like this for eg your green button.
<TouchableOpacity style={[styles.greenB, this.state.greenB]} onPress={this.state.canPress && () => { 
  this.playerTurn(1);
  // Whatever you want to do on green button pressed by player in here.
}>
</TouchableOpacity>

this.setState also has a callback function as its second parameter, which may be more useful in your flash method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM