Как отменить щелчок по ячейке таблицы в React

#css #reactjs #html-table #onclick

#css #reactjs #html-таблица #onclick

Вопрос:

У меня есть таблица, которую я создал в React. Я хочу иметь возможность раскрашивать ячейку, если я нажимаю на нее, и отменять ее, если я нажимаю на другую ячейку (вместо этого новая ячейка будет окрашена).

Я могу успешно раскрашивать ячейки при нажатии на них, но я не уверен, как их отменить, поскольку объект cell не знает, когда был сделан щелчок по другой ячейке. (Хотя я не могу придумать ничего в объекте row / table, что могло бы знать об этом.) В результате я получаю кучу цветных ячеек, если щелкаю несколько раз, а не только одну.

Вот мой код ячейки:

 class Cell extends React.Component {

    state = {
        bgColor: 'inherit'
      }

    handleClick = (columnId) => {
        this.setState({
            bgColor: "blue"
        })
    }

    render() {

        const content = this.props.content;

        return (
            <td
                onClick={()=> this.handleClick()}
                style={{backgroundColor: this.state.bgColor}}
            >
                {content}
            </td>
        )
    }
}
  

Заранее спасибо за вашу помощь!

Ответ №1:

Я могу успешно раскрашивать ячейки при нажатии на них, но я не уверен, как их отменить, поскольку объект cell не знает, когда был сделан щелчок по другой ячейке

Вам нужен единый источник достоверности, чтобы ваши компоненты знали, кто активен. В приведенном ниже примере я поместил activeCell состояние в родительский компонент App , чтобы в нем содержалось истинное значение того, кто активен. Передайте реквизиты вниз по to Cell по мере необходимости для обновления нового activeCell щелчка

 class Cell extends React.Component {
  render() {

    const content = this.props.content;

    return (
      <td
          onClick={()=>{this.props.handleChangeActiveCell(this.props.identifier)}}
          style={{backgroundColor: this.props.activeCell === true ? this.props.bgColor : 'inherit'}}
      >
          {content}
      </td>
    )
  }
}

class App extends React.Component {

  state = {
    bgColor: "blue",
    activeCell: -1
  }
  
  handleChangeActiveCell = (key) => {
    this.setState({
      activeCell: key
    });
  }

  render(){
    return(
      <React.Fragment>
        <table>
          <tr>
            <Cell 
              identifier={0} 
              handleChangeActiveCell={this.handleChangeActiveCell} 
              activeCell={this.state.activeCell === 0 ? true : false} 
              bgColor={this.state.bgColor} 
              content={`sample_content`}
            />
            
            <Cell 
              identifier={1} 
              handleChangeActiveCell={this.handleChangeActiveCell} 
              activeCell={this.state.activeCell === 1 ? true : false} 
              bgColor={this.state.bgColor} 
              content={`sample_content`}
            />
          </tr>
        </table>
      </React.Fragment>
    );
  }
}

ReactDOM.render(<App/>, document.getElementById("root"));  
 td {
  cursor: pointer;
}  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>  

Комментарии:

1. Спасибо, это имеет большой смысл!

2. Добро пожаловать. В дальнейшем это будет обычной практикой в ваших приложениях. Помните, что если компоненту A и компоненту B необходимо знать состояние друг друга, вы можете позволить их родительскому элементу сохранить это состояние и передать его в качестве реквизита обоим компонентам, а затем выполнить некоторую логику. Если это «состояние» должно сохраняться во всем приложении, вы можете рассмотреть возможность использования контекста React.

3. Да, ваш ответ во многом прояснил для меня эту практику. 🙂