简体   繁体   中英

How to change the value of buttons undependable React.js

I am trying to build a tic-tac-toe game using class to practice passing the props to child components and lifting up the state of component that's why you can see my creating 4 components.

The problem I need help with is so that when I click one of the buttons all buttons change their value at the same time.

I need to make each button display its own value separately. I declared a function and gave it functionality to change the state from null to X or O.

// App component 
class App extends React.Component {
  constructor(props) {
    super(props);
 
  }
  render() {
    return (
      <>
        <Board />
      </>
    );
  }
}

// Board component 
class Board extends React.Component{
  constructor(props){
    super(props);
    this.state = {txt: 'X'};
    this.change = this.change.bind(this);
  }
  change(){
    const updt = (this.state.txt === 'X' || this.state.txt === '0') ? 'O' : 'X';
    this.setState({txt: updt}); 
  }
  render() {
    return(
       <>
        <div>
          <Row key={'1'} value={this.state.txt} change={this.change}/>
          <Row key={'2'} value={this.state.txt} change={this.change}/>
          <Row key={'3'} value={this.state.txt} change={this.change}/>
        </div>
      </>
    )
  }
}

// Box component 
function Box(props){
  return (
    <>
      <button  className='class1' onClick={props.change} >{props.value}</button>
    </>
  );
}

// Row component 
function Row(props){
    return (
      <>
        <div id='myId'>
          <Box change={props.change} value={props.value}/>
          <Box change={props.change} value={props.value}/>
          <Box change={props.change} value={props.value}/>
        </div>
      </>
    )
}


ReactDOM.render(<App/>, document.querySelector('#root'));

all of your button change text because you literally passing them the same value, instead you need to create an array of rows each row contains an array of buttons, and then you map over these array like I'm down down below, that's how things are meant to be don in react. I also added a user turn functionality.

// App component 
class App extends React.Component {
  constructor(props) {
    super(props);
 
  }
  render() {
    return (
      <>
        <Board />
      </>
    );
  }
}

// Board component 
class Board extends React.Component{
  constructor(props){
    super(props);
    this.state = {
turn:"X",

rows:[
//ROW 1 
         [
            {
            id:"btn1",
            text:"0"
            },
            {
            id:"btn2",
            text:"0"
            },
            {
            id:"btn3",
            text:"0"
            },
         ],
//ROW 2 
         [
            {
            id:"btn1",
           text:"0"
            },
            {
            id:"btn2",
            text:"0"
            },
            {
            id:"btn3",
            text:"0"
            },
         ],
//ROW 3 
         [
            {
            id:"btn1",
             text:"0"
            },
            {
            id:"btn2",
             text:"0"
            },
            {
            id:"btn3",
            text:"0"
            },
         ],
    ]};
    this.change = this.change.bind(this);
  }

  change(rowIndex,btnId,btnLastValue){
   
    const updt = (btnLastValue === 'X' || btnLastValue === '0') ? 'O' : 'X';
    let tempState= [...this.state.rows]
    const targetBtn= tempState[rowIndex].filter(btn=>btn.id==btnId)[0]
    const targetBtnIndex= tempState[rowIndex].indexOf(targetBtn)
    
    let updateText = this.state.turn=="X" ? "X": "O"
    const tempState[rowIndex][targetBtnIndex].text= updateText 
    
    this.setState({...this.state,rows: tempState, trun:updateText }); 
  }

  render() {
    return(
       <>
        <div>
          {
           this.state.rows.map((row,index)=><Row 
           key={index} 
           rowIndex={index} 
           row={row} 
           change={this.change}
           />
           )
          }
        </div>
      </>
    )
  }
}

// Box component 
function Box(props){
 const {value,rowIndex,change}=props
  return (
    <>
      <button  className='class1' onClick={e=>change(rowIndex,value.id,value.text)} >{props.value}</button>
    </>
  );
}

// Row component 
function Row(props){
    const {row,rowIndex,change}=props

    return (
      <>
        <div id='myId'>
           {
            rows.map(btn =><Box 
            change={change} 
            rowIndex={rowIndex} 
            value={btn}
            />)
            }  
        </div>
      </>
    )
}


ReactDOM.render(<App/>, document.querySelector('#root'));

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