简体   繁体   中英

React Js: Only change the class of the table cell that has been clicked

I'm creating a pathfinding app. I would like the user to be able to draw its own walls in between points A to B. I only need change the class of each table cell clicked. However I have only been able to change the class of every table cell, regardless of which table cell is clicked. I am completely stump on where to go. Ideally the user would be able to click and drag across the grid instead of having to click each induvial table cell. Cheers:)

Grid.js

import React, { Component } from "react";

import Xnode from "./Xnode";
import Ynode from "./Ynode";

export class Grid extends Component {
  constructor(props) {
    super(props);
    this.state = {
      path: true,
      wall: false,
      Xactive: this.state,
      Yactive: this.state,
    };
  }
  
  render() {
    let rows = [];
    let columns = [];

    for (let i = 0; i < 60; i++) {
      columns[i] = (
        <td
          className={this.state.wall ? "wall" : "grid"}
          onClick={() => this.setState({ wall: true })}
          id={i}
          key={i}
        ></td>
      );
    }

    for (let i = 0; i < 25; i++) {
      rows[i] = (
        <tr id={i.toString()} key={i.toString()}>
          {columns}
        </tr>
      );
    }

    return (
      <div>
        <table className="grid">
          <tbody>{rows}</tbody>
        </table>
      </div>
    );
  }
}

export default Grid;

App.js


import './App.css';

import React from 'react';
import {
  BrowserRouter as Router,
  Route,
} from 'react-router-dom';

import './App.css';

import Grid from './components/Grid';

export default () => (
  <Router>
    <div >
        <Route exact path="/" component={Grid} />
</div>
  </Router>
  
);

CSS

 table.grid {
  margin: 80px auto;
  border: 5px solid #333;
  border-collapse: collapse; /* */
}

td.grid {
  width: 15px; height: 15px;
  border: 1.5px solid #333; /* */
}

td.wall {
  width: 15px; height: 15px;
  background-color: black;
  border: 1.5px solid #333; /* */
}

.node-x {
  background-color: mediumaquamarine ;
  border: 2px solid black;
  border-radius: 50%;
  width: 20px;
  height: 20px;
}

.node-y {
  background-color: red ;
  border: 2px solid black;
  border-radius: 50%;
  width: 20px;
  height: 20px;
}

So, every one of your table cells' class is dependent on the state of the grid, and when any table cell is clicked the grid's state changes. It looks to me like the td elements should be their own component and have their own state as well. Something like:

class MyTD extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isClicked: false
    }
  }

  render(){
    <td 
      onClick={() => {this.props.handleClick(); this.setState({isClicked: true});}}
      className={this.state.isClicked ? "wall" : "grid"}
    </td>
  }
}

Then in your Grid component:

//for loop
<MyTD key={i} handleClick={() => this.setState({wall: true})}/>

This is assuming you need your child components to change the state of the parent grid. If they don't, and the click only needs to change their own state, you don't even need to pass a click handler.

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