React如何通过click事件使用不同的状态

时间:2020-01-19 00:04:19

标签: javascript reactjs react-native react-native-android state

简而言之: 我正在React Native中实现Simon-Says游戏应用程序。 (用户看到一系列闪烁的按钮,需要按正确的顺序按下按钮。)

我想知道如何在TouchableOpacity中使用2种不同的状态,其中一种状态是按下按钮的条件,一种是更改按钮样式的条件,并且还针对此特定的按下状态得到通知。

所以

我在实现playerTurn()时遇到问题, 因为我不确定如何将canPress状态传递给TouchableOpacity按钮, 考虑到我传递了compTurn()中发生变化的样式状态 (该功能显示一系列闪烁的按钮-然后计算机翻转过来) 在玩家回合中,我需要考虑的事情:

  1. 状态canPress更改后,将允许用户按按钮
  2. 用户按下四个按钮之一
  3. 将向方法playerTurn()通知玩家按下了哪个按钮。 (我在问我如何从按钮到方法的通知?) 之后,我可以将其选择项推送到playerSeq数组(如果按下绿色-按下1,等等),然后调用更改样式状态的函数(例如greenFlash)

简码:

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

完整代码:(不是完整的游戏,请注意,我最近几天正在学习做出反应)

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',
  }

});

1 个答案:

答案 0 :(得分:2)

如果state.canPress = true对,您是否想启用单击按钮?然后,单击后,您希望通过调用playerTurn()来通知吗?

  1. 您可以为绿色按钮执行类似操作。
<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还有一个回调函数作为第二个参数,在您的flash方法中可能更有用。