React 如何在点击事件中使用不同的状态

React How to use different states with click event

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

我想知道如何在 TouchableOpacity 中使用 2 种不同的状态,其中一种作为按下按钮的条件,一种用于更改按钮的样式,并在特定按下时收到通知。

所以,

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

  1. 状态 canPress 更改后,将允许用户按下按钮
  2. 用户按下 4 个按钮之一
  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

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

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

});

如果 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方法中可能更有用。